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