ios - GCD Semaphore does not wait (Swift) -
i'm pretty new gcd. have function forward geocoding , issue returns before completion closure completes. every time returns nil. found out can use semaphores return waits completion closure complete, there little examples online , found none of function returns. tried implement it, function still returns nil though location printed out console moments later. if tell me making mistake grateful.
func forwardgeocoding(address: string) -> cllocation? { var userlocation: cllocation? var returnvalue: cllocation? let semaphore = dispatch_semaphore_create(0) clgeocoder().geocodeaddressstring(address, completionhandler: { (placemarks, error) in if error != nil { print("geocoding error: \(error)") return } if placemarks?.count > 0 { let placemark = placemarks?.first let location = placemark?.location let coordinate = location?.coordinate print("settings location: \(coordinate!.latitude), \(coordinate!.longitude)") if let unwrappedcoordinate = coordinate { let clreadylocation: cllocation = cllocation(latitude: unwrappedcoordinate.latitude, longitude: unwrappedcoordinate.longitude) userlocation = clreadylocation dispatch_semaphore_signal(semaphore) } } }) let wait = dispatch_semaphore_wait(semaphore, dispatch_time_forever) if wait != 0 { returnvalue = userlocation } return returnvalue }
as paulw11 mentioned, semaphore in case bad programming habit. if new gcd learn understand asynchronous pattern returning received data in completion block. it's simpler handle in swift in objective-c.
this example using completion block:
func forwardgeocoding(address: string, completion: (cllocation?, nserror?) -> void) { clgeocoder().geocodeaddressstring(address, completionhandler: { (placemarks, error) in if error != nil { completion(nil, error!) } else { if let placemarks = placemarks !placemarks.isempty { let placemark = placemarks.first! if let unwrappedlocation = placemark.location { let coordinate = unwrappedlocation.coordinate print("settings location: \(coordinate.latitude), \(coordinate.longitude)") let clreadylocation = cllocation(latitude: coordinate.latitude, longitude: coordinate.longitude) completion(clreadylocation, nil) } } } }) }
and call with
forwardgeocoding("foo") { (location, error) in if error != nil { print("geocoding error: \(error!)") } else { // location } }
Comments
Post a Comment