Закрытие для отображения результатов reverseGeocoder в Swift - PullRequest
0 голосов
/ 19 октября 2018

В ответ на действие пользователя я хотел бы преобразовать CLLocation в адресную строку и отобразить ее обратно пользователю.

Последовательность поэтому равна 1. Действие пользователя запускает последовательность 2. ReverseGeocoder делает запросна серверы Apple и возвращает результаты асинхронно.3. Отображает результаты для пользователя.

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

  func userWantsAddress {        
    displayAddressFrom(location: myLocation)
    }
     func displayAddressFrom(location: CLLocation)  {
            CLGeocoder().reverseGeocodeLocation(location) { (placemark, error) in
                if error != nil {
                    print("error")

                } else {

                    let place = placemark! as [CLPlacemark]
                    if place.count > 0 {
                        let place = placemark![0]
                        var addressString : String = ""
                        if place.subThoroughfare != nil {
                            addressString = addressString + place.subThoroughfare! + "\n"
                        }
                        if place.thoroughfare != nil {
                            addressString = addressString + place.thoroughfare! + " in "
                        }

                        if place.locality != nil {
                            addressString = addressString + place.locality!
                        }

                        if place.subAdministrativeArea != nil {
                            addressString = addressString + ", "+place.subAdministrativeArea!
                        }
    //THIS IS WHERE YOU DISPLAY
                        myLabel.text = "THE LOCATION IS \(addressString)"
                        print("the location is",addressString)

                    }
                }
            }

        }

Что бы я хотелоднако это упрощает код, поэтому после получения результатов возвращайте их в закрытии вызывающему методу для настройки, чтобы я мог повторно использовать метод addressFromString (и не нужно переписывать его каждый раз, когда я хочу преобразоватьместоположение в адрес), но я не могу понять синтаксис.

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

    func userWantsAddress(location: myLocation completion:@escaping (_ response:String)->()){

        displayAddressFrom(location: myLocation completion:completion) {

completion("HERE IS YOUR ADDRESS")
        }

Однако я не могу понять это правильно

Буду признателен за любые предложения о том, как это сделать.

1 Ответ

0 голосов
/ 19 октября 2018

Вам просто нужно добавить обработчик завершения к своему методу и вернуть первую метку при вызове завершения:

func displayAddressFrom(location: CLLocation, completion: @escaping (CLPlacemark?, Error?) -> ())  {
    CLGeocoder().reverseGeocodeLocation(location) { 
        completion($0?.first, $1) 
    }
}

let location = CLLocation(latitude: -22.963451, longitude: -43.198242)
displayAddressFrom(location: location) { placemark, error in
    guard let placemark = placemark, error == nil else { return }
    // Update your UI from the main thread
    DispatchQueue.main.async {
        //  UI update here
        print(placemark)
    }
}

Морро да Саудаде, Морро даСаудаде, Руа Казуарина, 443, Лагоа, Рио-де-Жанейро - RJ, 22011-040, Бразилия @ <-22.96345100, -43.19824200> +/- 100.00 м, регион CLCircularRegion (идентификатор: '<- 22.96345100, -43.19824200> радиус 141.83', центр: <- 22.96345100, -43.19824200>, радиус: 141.83 м)


Если вам нужна строка почтового отправления из вашей метки, вы можете получить ее postalAddress и создать из нее строку, используя CNPostalAddressFormatterСтрока (для метода :):

import Contacts
extension CNPostalAddress {
    var mailingAddress: String {
        return CNPostalAddressFormatter.string(from: self, style: .mailingAddress)
    }
}

DispatchQueue.main.async {
    //  UI update here
    print(placemark.postalAddress?.mailingAddress ?? "")   // "Rua Casuarina, 443\nLagoa\nRio de Janeiro RJ\n22011-040\nBrazil"
}

Руа Казуарина, 443 Lagoa Рио-де-Жанейро, RJ 22011-040 Бразилия

...