swiftmapkitclgeocodercllocationcoordinate2dclplacemark

Swift Completion Handler for Reverse Geocoding


I have been banging my head in order to figure out how to fix this piece of code. Basically I have a piece of code that takes a string cityName and stores the latitude and longitude of it in a global variable and call it in another function right after. Apparently because of asynchronous call, I am not able to do that and the value of longitude and latitude are nil.

func findCityCoordinates(cityName: String)  {
        var geocoder = CLGeocoder()

        geocoder.geocodeAddressString(cityName, completionHandler: {(placemarks: [AnyObject]!, error: NSError!) -> Void in
            if let placemark = placemarks?[0] as? CLPlacemark {

              self.cityLatitude = placemark.location.coordinate.latitude //Returns nil
              self.cityLongitude = placemark.location.coordinate.longitude //Returns nil
            }
        })
    }

I have also been trying to work around completion handler but I have no idea on how to implement it and call it in a function. I would appreciate some help.


Solution

  • Well my brother helped me a little bit out on this, basically I wanted to run a completion block in the IBAction of the save button instead inside of the function findCityCoordinates:

     func findCityCoordinate(city: String, completionHandler: (coordinate: CLLocationCoordinate2D) -> ()) { 
          let geocoder = CLGeocoder() 
          geocoder.geocodeAddressString(city) { (placemarks: [AnyObject]!, error: NSError!) -> () in 
              if let placemark = placemarks[0] as? CLPlacemark { 
                  let coordinate = placemark.location.coordinate 
                  completionHandler(coordinate: coordinate) 
              } 
          } 
     }
    

    And heres the function being called inside the saveButton action outlet:

     findCityCoordinates(searchBar.text) { (cityCoordinate: CLLocationCoordinate2D) -> () in
         self.queryForTable(cityCoordinate)
         // Force reload of table data
         self.myTableView.reloadData()
     }