ios - 在 Swift 中显示 reverseGeocoder 结果的闭包

标签 ios swift closures

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

因此顺序是 1. 用户 Action 触发序列 2. ReverseGeocoder 向Apple 服务器发出请求并异步返回结果。 3. 向用户显示结果。

如果我在完成 block 中有一个专用的显示部分的方法,我就能够显示结果,如下所示:

  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 方法(并且不必重写每次我想将位置转换为地址时都会使用它)但我无法弄清楚语法。

我想我需要给第一个方法一个完成 block 来等待第二个方法完成。并在闭包中获得第二个返回结果:类似于:

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

        displayAddressFrom(location: myLocation completion:completion) {

completion("HERE IS YOUR ADDRESS")
        }

然而,我似乎无法做到这一点

对于如何执行此操作的任何建议,我们将不胜感激。

最佳答案

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

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 Janeiro - RJ, 22011-040, Brazil @ <-22.96345100,-43.19824200> +/- 100.00m, region CLCircularRegion (identifier:'<-22.96345100,-43.19824200> radius 141.83', center:<-22.96345100,-43.19824200>, radius: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 Brazil

关于ios - 在 Swift 中显示 reverseGeocoder 结果的闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52899366/

相关文章:

ios - 将 UIImage 绘制为 MKMapView 的 subview 与将其绘制为 map View 中的注释相比,对 CPU 的压力更小。为什么?

ios - swift - 我可以比较 Any.Type 吗?

swift - 无法使用 params 作为字典与 Swift 4 和 Alamofire 发出发布请求

ios - 如何将通用自定义对象保存到 UserDefaults?

JavaScript 闭包和变量作用域

ios - SharedHTTPCookieStorage cookie 是否本地存储在 IOS 应用程序中?

ios - UIBarButtonItem 在启用后不会更改默认蓝色

ios - 核心数据中的谓词和组合过滤器?

multithreading - 一个 Rust 闭包可以被多个线程使用吗?

javascript - 如何将变量按值传递给匿名 JavaScript 函数?