Search code examples
swiftclgeocoder

How to wait until CLGeocoder finish its work


I have following function geocoding address from GPS coordinates

private func getAddressFromLocation(forLocation: CLLocationCoordinate2D) {
    let geoCoder = CLGeocoder()
    geoCoder.reverseGeocodeLocation(CLLocation(latitude: forLocation.latitude, longitude: forLocation.longitude), completionHandler: {(places, error) in
        guard error == nil else {
            return
        }
        let place: CLPlacemark = places!.first!
        var address: [String] = []
        if place.country != nil { address.append(place.country!) }
        if place.postalCode != nil { address.append(place.postalCode!) }
        if place.locality != nil { address.append(place.locality!) }
        if place.thoroughfare != nil { address.append(place.thoroughfare!) }
        self.fullAddress = address.joined(separator: ",")
    })
}

Function is called from another part of my application and I'm wondering how to ensure that program will wait until fullAddress variable got value (function finish). I tried to put function call into sync dispatch queue but it didn't help. Thanks for any suggestion.


Solution

  • yes, completion handlers are going to be your friend here:

    typealias CompletionHandler = (_ success:Bool) -> Void
    
    private func getAddressFromLocation(forLocation: CLLocationCoordinate2D, completionHandler: @escaping CompletionHandler) {
        let geoCoder = CLGeocoder()
        geoCoder.reverseGeocodeLocation(CLLocation(latitude: forLocation.latitude, longitude: forLocation.longitude), completionHandler: {(places, error) in
            guard error == nil else {
                completionHandler(false)
                return
            }
            let place: CLPlacemark = places!.first!
            var address: [String] = []
            if place.country != nil { address.append(place.country!) }
            if place.postalCode != nil { address.append(place.postalCode!) }
            if place.locality != nil { address.append(place.locality!) }
            if place.thoroughfare != nil { address.append(place.thoroughfare!) }
            print("address: \(address.joined(separator: ","))")
            completionHandler(true)
        })
    }
    

    You can call this like so:

    getAddressFromLocation(forLocation: CLLocationCoordinate2D()) { success in
        if success {
            //once address is fetched, this will be triggered.
        }
    }