3

I'm attempting to use CLGeocoder to return the location of coordinates in a string. My code currently looks like this:

func getPlaceName(latitude: Double, longitude: Double) -> String {

let coordinates = CLLocation(latitude: latitude, longitude: longitude)
var answer = ""

CLGeocoder().reverseGeocodeLocation(coordinates, completionHandler: {(placemarks, error) -> Void in
    if (error != nil) {
        println("Reverse geocoder failed with an error" + error.localizedDescription)
answer = ""
    }

    if placemarks.count > 0 {
        let pm = placemarks[0] as CLPlacemark
        answer = displayLocationInfo(pm)
    } else {
        println("Problems with the data received from geocoder.")
answer = ""
    }
})

return answer

}

func displayLocationInfo(placemark: CLPlacemark?) -> String
{
if let containsPlacemark = placemark
{

    let locality = (containsPlacemark.locality != nil) ? containsPlacemark.locality : ""
    let postalCode = (containsPlacemark.postalCode != nil) ? containsPlacemark.postalCode : ""
    let administrativeArea = (containsPlacemark.administrativeArea != nil) ? containsPlacemark.administrativeArea : ""
    let country = (containsPlacemark.country != nil) ? containsPlacemark.country : ""

    println(locality)
    println(postalCode)
    println(administrativeArea)
    println(country)

    return locality

} else {

    return ""

}

}

Everything seems to be working, apart from being able to return the string from getPlaceNames(). I only every get the following returned:

Optional("")

The displayLocationInfo() function seems to work fine, as the println()s come out ok. So I believe that the getPlaceName() function is indeed getting the locality string from displayLocationInfo().

Any ideas? Thanks.

Adam Johnson
  • 673
  • 9
  • 18
  • reverseGeocodeLocation is asynchronous. Your return statement will be executed on the main thread before reverseGeocodeLocation finishes. – ad121 Mar 23 '15 at 19:57
  • Is there an easy way around this? I have tried returning directly from the CLGeocoder(), but it's telling me I can't return a String due to it being Void. I've played around and tried telling it to return a string, but it's obviously not liking that either. Thanks. – Adam Johnson Mar 23 '15 at 20:08
  • You should set up a completion block for your function getPlaceName and just pass the answer through that block instead of trying to use a return statement – ad121 Mar 23 '15 at 20:31
  • I posted an example of making a function with a completion block – ad121 Mar 23 '15 at 20:39

1 Answers1

7

Since reverseGeocodeLocation is an asynchronous function, you need to make your getPlaceName function pass the answer back via a block instead of a return statement. Example:

func getPlaceName(latitude: Double, longitude: Double, completion: (answer: String?) -> Void) {

   let coordinates = CLLocation(latitude: latitude, longitude: longitude)

   CLGeocoder().reverseGeocodeLocation(coordinates, completionHandler: {(placemarks, error) -> Void in
       if (error != nil) {
           println("Reverse geocoder failed with an error" + error.localizedDescription)
           completion(answer: "")
       } else if placemarks.count > 0 {
           let pm = placemarks[0] as CLPlacemark
           completion(answer: displayLocaitonInfo(pm))
       } else {
           println("Problems with the data received from geocoder.")
           completion(answer: "")
       }
   })

}
ad121
  • 2,268
  • 1
  • 18
  • 24
  • Thanks for all the help. I'm stumped on how to call the function. I've taken a look on a few websites (with the one at https://thatthinginswift.com/completion-handlers seeming to be the most beginner-friendly), but I still can't figure out how to add that extra completion argument. – Adam Johnson Mar 23 '15 at 21:02
  • The closet I've come to working this out so far is it: 'getPlaceName(Double(latitude), Double(longitude), { (answer) -> Void in println(answer) })' – Adam Johnson Mar 23 '15 at 22:05
  • Figured it out! Thank you for the help, ad121. – Adam Johnson Mar 23 '15 at 22:09
  • No problem... glad you figured it out. – ad121 Mar 24 '15 at 02:22