【问题标题】:Closure for displaying results of reverseGeocoder in Swift在 Swift 中显示 reverseGeocoder 结果的闭包
【发布时间】:2019-03-24 18:12:54
【问题描述】:

为了响应用户操作,我想将 CLLocation 转换为地址字符串并将其显示给用户。

因此序列是 1. 用户动作触发顺序 2. ReverseGeocoder 向苹果服务器发出请求并异步返回结果。 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")
        }

但是,我似乎无法做到这一点

如果您提供有关如何执行此操作的任何建议,我们将不胜感激。

【问题讨论】:

    标签: ios swift closures


    【解决方案1】:

    您只需在方法中添加一个完成处理程序,并在调用完成时返回第一个地标:

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

    Morro da Saudade, Morro da Saudade, Rua Casuarina, 443, Lagoa, Rio de 热内卢 - RJ,22011-040,巴西 @ +/- 100.00m,区域 CLCircularRegion(标识符:' 半径 141.83', 中心:,半径:141.83m)


    如果您需要地标中的邮寄字符串,您可以获取其 postalAddress 并使用 CNPostalAddressFormatter string(for:) 方法从中创建一个字符串:

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

    Rua Casuarina, 443 Lagoa Rio de Janeiro RJ 22011-040 巴西

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2015-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多