Swift Completion для обратного геокодирования

Я бился головой, чтобы понять, как исправить этот кусок кода. В основном у меня есть кусок кода, который принимает строку cityName и сохраняет ее широту и долготу в глобальной переменной и сразу вызывает ее в другой функции. Видимо из-за асинхронного вызова я не могу этого сделать, а значения долготы и широты равны нулю.

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
            }
        })
    }

Я также пытался обойти обработчик завершения, но я понятия не имею, как реализовать его и вызвать его в функции. Буду признателен за помощь.

3 ответа

Решение

Ну, мой брат немного помог мне с этим, в основном я хотел запустить блок завершения в IBAction кнопки сохранения вместо функции 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) 
        } 
    } 
}

И вот функция вызывается внутри выхода действия saveButton

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

        }

Я смог использовать асинхронную отправку для этого. Я объявил две переменные над геокодером, назначил их внутри и использовал после завершения.

var lat:Float!
var long:Float!
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(cityName, completionHandler: {(placemarks: [AnyObject]!, error: NSError!) -> Void in
    if let placemark = placemarks?[0] as? CLPlacemark {
         lat = Float(placemark.location.coordinate.latitude)
         long = Float(placemark.location.coordinate.longitude)
     }
     dispatch_async(
         dispatch_get_main_queue(), {
            self.cityLatitude = lat 
            self.cityLongitude = long 
      })
})

... сохраняет широту и долготу в глобальной переменной и сразу же вызывает ее в другой функции

Я подозреваю, что другая функция использует его до того, как блок завершения геокодера установит значения. Переведите вызов другой функции в блок завершения, если это возможно.

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

             *** <-- call your function that uses location here --> ***
            }
        })
    }
Другие вопросы по тегам