I want to wrap the geocoder.geocdeAddressString in another method with other logic.
public func placemarkForSearchResult<T>(searchResult: T) -> CLPlacemark? {
if let searchResult = searchResult as? String {
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(searchResult, completionHandler: {
(placemarks, error) -> Void in
// Check for returned placemarks
if let placemarks = placemarks where placemarks.count > 0 {
return placemarks[0] as! CLPlacemark // CLPlacemark is not convertible to void error message
}
return nil // Typd Void does not conform to protocol NilLiteralConvertible
})
}
}
I have some other logic in this method that's not really relevant, but I was wondering how I can handle a situation like this where I want to return a CLPlacemark, but cannot because the completionHandler for the geocoder returns Void. I cannot change the Void parameter of the geocoder callback. Is that possible? Or am I stuck with calling a delegate method that uses the found CLPlacemark from the geocoder? Thanks in advance.
You can never return a placemark from your
placemarkForSearchResult
function, because obtaining a placemark requires the use of an asynchronous function (geocodeAddressString
). By that time that function has finished and calls back into your completion handler, yourplacemarkForSearchResult
has already finished and returned long ago!You need a strategy compatible with the asynchronous nature of the function you are calling. Instead of returning a placemark from
placemarkForSearchResult
, you needplacemarkForSearchResult
to accept a callback function parameter. When you have your placemark in the completion handler, you call that callback function. If that callback function is (cleverly) designed to accept a placemark parameter, you are now handing that placemark to whoever called you in the first place.