Swift - CLGeocoder reverseGeocodeLocation completionHandler闭包

Aar*_*cer 22 mapkit mkmapview cllocation ios swift

我正在试图做的是传递CLLocation给函数getPlacemarkFromLocation,然后使用传递CLLocation通过reverseGeocodeLocation设置CLPlacemark?将返回.

我在创建completionHandler闭包时遇到问题reverseGeocodeLocation,它会抛出编译器错误/崩溃:


在斯威夫特,CLGeocodeCompletionHandlerCLGeocodeCompletionHandler = (AnyObject[]!, NSError!) -> Void根据文档AnyObject[]!应该包含CLPlacemark的对象,就像Objective-C的版本.

这是我目前的代码:

class func getPlacemarkFromLocation(location:CLLocation)->CLPlacemark?{
    var g = CLGeocoder()
    var p:CLPlacemark?
    g.reverseGeocodeLocation(location, completionHandler: {
        (placemarks, error) in
        let pm = placemarks as? CLPlacemark[]
        if (pm && pm?.count > 0){
            p = placemarks[0] as? CLPlacemark
        }
    })
    return p?
}
Run Code Online (Sandbox Code Playgroud)

编辑:似乎错误placemarks.countplacemarks没有像数组一样对待.它现在编译,但是当我试图进入p内部时,我只得到零completionHandler.我检查了CLLocation被传递的内容并且它们是有效的.

编辑2:打印后placemarks,我可以确认它返回数据.然而p,仍然返回零.

Aar*_*cer 23

我在这个帖子中找到了我需要的答案:使用reverseGeocodeLocation设置地址字符串:并从方法返回

问题在于reverseGeocodeLocation异步,该方法p在我的示例中在completionBlock设置之前返回一个值.


根据要求,这是我目前的代码.

func showAddViewController(placemark:CLPlacemark){
    self.performSegueWithIdentifier("add", sender: placemark) 
}

func getPlacemarkFromLocation(location: CLLocation){
    CLGeocoder().reverseGeocodeLocation(location, completionHandler:
        {(placemarks, error) in
            if error {println("reverse geodcode fail: \(error.localizedDescription)")}
            let pm = placemarks as [CLPlacemark]
            if pm.count > 0 { self.showAddPinViewController(placemarks[0] as CLPlacemark) }
    })
}
Run Code Online (Sandbox Code Playgroud)

我不想采用NSNotificationCenter路由,因为这会增加不必要的开销,而是在completionHandler闭包内我调用另一个函数并将CLPlacemark生成的by getPlacemarkFromLocation作为参数传递以保持异步,因为在placemarks设置函数之后函数将被调用(应该)收到所需的地标并执行你想要的代码.希望我所说的是有道理的.


Goo*_*yen 15

使用这些Swift系列,您可以完全打印出该位置的地址:

func getLocationAddress(location:CLLocation) {
    var geocoder = CLGeocoder()

    println("-> Finding user address...")

    geocoder.reverseGeocodeLocation(location, completionHandler: {(placemarks, error)->Void in
        var placemark:CLPlacemark!

        if error == nil && placemarks.count > 0 {
            placemark = placemarks[0] as CLPlacemark

            var addressString : String = ""
            if placemark.ISOcountryCode == "TW" /*Address Format in Chinese*/ {
                if placemark.country != nil {
                    addressString = placemark.country
                }
                if placemark.subAdministrativeArea != nil {
                    addressString = addressString + placemark.subAdministrativeArea + ", "
                }
                if placemark.postalCode != nil {
                    addressString = addressString + placemark.postalCode + " "
                }
                if placemark.locality != nil {
                    addressString = addressString + placemark.locality
                }
                if placemark.thoroughfare != nil {
                    addressString = addressString + placemark.thoroughfare
                }
                if placemark.subThoroughfare != nil {
                    addressString = addressString + placemark.subThoroughfare
                }
            } else {
                if placemark.subThoroughfare != nil {
                    addressString = placemark.subThoroughfare + " "
                }
                if placemark.thoroughfare != nil {
                    addressString = addressString + placemark.thoroughfare + ", "
                }
                if placemark.postalCode != nil {
                    addressString = addressString + placemark.postalCode + " "
                }
                if placemark.locality != nil {
                    addressString = addressString + placemark.locality + ", "
                }
                if placemark.administrativeArea != nil {
                    addressString = addressString + placemark.administrativeArea + " "
                }
                if placemark.country != nil {
                    addressString = addressString + placemark.country
                }
            }

            println(addressString)
        }
    })
}
Run Code Online (Sandbox Code Playgroud)

干杯!