Search code examples
iosswiftcllocationclgeocodercllocationcoordinate2d

iOS Swift - CLGeocoder completionHandler block


I'm trying to parse a location (CLLocation) into a String.

    func locationToString (currentLocation: CLLocation) -> String? {
    var whatToReturn: String?
    CLGeocoder().reverseGeocodeLocation(currentLocation, completionHandler: { (placemarks: [AnyObject]!, error: NSError!) in
        if error == nil && placemarks.count > 0 {
            let location = placemarks[0] as CLPlacemark
            whatToReturn = "\(location.locality) \(location.thoroughfare) \(location.subThoroughfare)"

        }
    })
    return whatToReturn
}

Obviously, whatToReturn always returns null, because completionHandler runs in the background. I'm having a hard time understanding how do I update my String when completionHandler finishes?

Thanks.


Solution

  • If you want to use your string in a textField, like indicated in your comments, do this:

    func getAndDisplayLocationStringForLocation(currentLocation: CLLocation) {
        CLGeocoder().reverseGeocodeLocation(currentLocation, completionHandler: { (placemarks: [AnyObject]!, error: NSError!) in
            if error == nil && placemarks.count > 0 {
                let location = placemarks[0] as CLPlacemark
                self.textField.text = "\(location.locality) \(location.thoroughfare) \(location.subThoroughfare)"
    
            }
        })
    }
    

    However, if you need access elsewhere, perhaps pass a closure as an arg:

    func getAndDisplayLocationStringForLocation(currentLocation: CLLocation, withCompletion completion: (string: String?, error?, error: NSError?) -> ()) {
        CLGeocoder().reverseGeocodeLocation(currentLocation, completionHandler: { (placemarks: [AnyObject]!, error: NSError!) in
            if error == nil && placemarks.count > 0 {
                let location = placemarks[0] as CLPlacemark
                completion(string: "\(location.locality) \(location.thoroughfare) \(location.subThoroughfare)", error: nil)
    
            } else {
                completion(nil, error)
            }
        })
    }
    

    Then call like this:

    yourModel.getAndDisplayLocationStringForLocation(someLocation) { (string: String?, error: NSError?) -> () in
        if (error == nil) {
            self.textField.text = string
        }
    }
    

    You may want to handle error etc. differently. This should be enough to get you started.