Unable Return String from CLGeocoder reverseGeocodeLocation

﹥>﹥吖頭↗ 提交于 2021-02-05 07:56:26

问题


I want to write a function to reverse geocode a location and assign the resulting string into a variable. Following this post i've got something like this:

extension CLLocation {

    func reverseGeocodeLocation(completion: (answer: String?) -> Void) {

        CLGeocoder().reverseGeocodeLocation(self) {

            if let error = $1 {
                print("[ERROR] \(error.localizedDescription)")
                return
            }

            if let a = $0?.last {
                guard let streetName = a.thoroughfare,
                    let postal = a.postalCode,
                    let city = a.locality else { return }

                completion(answer: "[\(streetName), \(postal) \(city)]")
            }

        }
    }
}

For calling this function i've just got something like this:

location.reverseGeocodeLocation { answer in
    print(answer)
}

But instead i want to assign the string value of answer to a variable and i don't know how to pass that data out of the closure. What is the best way to do something like this?


回答1:


The problem is that it runs asynchronously, so you can't return the value. If you want to update some property or variable, the right place to do that is in the closure you provide to the method, for example:

var geocodeString: String?

location.reverseGeocodeLocation { answer in
    geocodeString = answer
    // and trigger whatever UI or model update you want here
}

// but not here

The entire purpose of the closure completion handler pattern is that is the preferred way to provide the data that was retrieved asynchronously.




回答2:


Short answer: You can't. That's not how async programming works. The function reverseGeocodeLocation returns immediately, before the answer is available. At some point in the future the geocode result becomes available, and when that happens the code in your closure gets called. THAT is when you do something with your answer. You could write the closure to install the answer in a label, update a table view, or some other behavior. (I don't remember if the geocoding methods' closures get called on the main thread or a background thread. If they get called on a background thread then you would need to wrap your UI calls in dispatch_async(dispatch_get_main_queue()).)



来源:https://stackoverflow.com/questions/38819750/unable-return-string-from-clgeocoder-reversegeocodelocation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!