0

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

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

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

ответ

0

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

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

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

     } 
1

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

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

Здорово, что получилось! Но он немного отстает на несколько секунд, и я использую parse PFGeoPoint для поиска объектов, находящихся вблизи этих координат, но, видимо, что-то не работает правильно. – emsqre

+0

Да, это немного медленно. Пользовательский интерфейс не должен замирать. Извините, я не знаком с Parse, поэтому не знаю, сколько еще я могу предоставить. – Caleb

+0

Эй Это было полезно, я мог бы использовать его в какой-то момент для других функций, которые не требуют немедленных действий. Но спасибо большое! – emsqre

0

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

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

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

Не могли бы вы показать мне, как это сделать в блоке соревнований? – emsqre

+0

См. Мои последние изменения. – MirekE

+0

Это IBAction, в основном кнопка поиска. Я не уверен, что смогу это сделать? – emsqre

Смежные вопросы