Reputation: 6861
I want to get a value from function. There is a block in function. When block executes the function already returns the value. I tried many different methods but they didn't help me. I used NSOperation
and Dispatch. The function always returns value until execution of block.
var superPlace: MKPlacemark!
func returnPlaceMarkInfo(coordinate: CLLocationCoordinate2D) -> MKPlacemark? {
let location = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
geocoder.reverseGeocodeLocation(location) { (arrayPlaceMark, error) -> Void in
if error == nil {
let firstPlace = arrayPlaceMark!.first!
let addressDictionaryPass = firstPlace.addressDictionary as! [String : AnyObject]
self.superPlace = MKPlacemark(coordinate: location.coordinate, addressDictionary: addressDictionaryPass)
}
}
return superPlace
}
Upvotes: 2
Views: 2244
Reputation: 7373
You cannot simply return here as the reverseGeocodeLocation function is running asynchronously so you will need to use your own completion block:
var superPlace: MKPlacemark!
func getPlaceMarkInfo(coordinate: CLLocationCoordinate2D, completion: (superPlace: MKPlacemark?) -> ()) {
let location = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
geocoder.reverseGeocodeLocation(location) { (arrayPlaceMark, error) -> Void in
if error == nil {
let firstPlace = arrayPlaceMark!.first!
let addressDictionaryPass = firstPlace.addressDictionary as! [String : AnyObject]
self.superPlace = MKPlacemark(coordinate: location.coordinate, addressDictionary: addressDictionaryPass)
completion(superPlace: superPlace)
} else {
completion(superPlace: nil)
}
}
}
Upvotes: 2
Reputation: 131511
This comes up over and over and over. The short answer is "you can't."
The result is not available when your function returns. The async call takes place in the background.
What you want to do is refactor your returnPlacemarkInfo function to take a completion closure.
I have been working in Objective-C lately, so my Swift is a little rusty, but it might look like this:
func fetchPlaceMarkInfo(
coordinate: CLLocationCoordinate2D,
completion: (thePlacemark: MKPlacemark?) -> () )
{
}
Then when you call it, pass in a completion closure that gets invoked once the placemark is available.
I wrote a demo project and posted it on Github that simulates handling an async network download. Take a look at
https://github.com/DuncanMC/SwiftCompletionHandlers
Specifically look at the method asyncFetchImage()
, which does almost exactly what we are talking about: Uses an async method internally, and takes a completion block that it calls once the async load is done.
Upvotes: 1