Swift – CLGeocoder reverseGeocodeLocation completionHandler闭包
我要做的是将CLLocation
传递给函数getPlacemarkFromLocation
,然后通过reverseGeocodeLocation
使用传递的CLLocation
来设置CLPlacemark?
将被退回。
我在reverseGeocodeLocation
创建completionHandler
闭包时reverseGeocodeLocation
, 它 reverseGeocodeLocation
了编译器错误/崩溃:
在Swift中, CLGeocodeCompletionHandler
是CLGeocodeCompletionHandler = (AnyObject[]!, NSError!) -> Void
根据文档AnyObject[]!
应该像Objective-C版本一样包含CLPlacemark
对象。
这是我目前的代码:
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? }
编辑:似乎错误与placemarks.count
, placemarks
不被视为数组。 它现在编译,但是当我尝试在completionHandler
设置p
时,我只得到nil。 我已经检查了传递的CLLocation
并且它们是有效的。
编辑2:打印placemarks
,我可以确认它返回数据。 然而, p
仍然没有返回。
我在这个post中找到了我需要的答案: 使用reverseGeocodeLocation设置地址字符串:并从方法返回
问题在于reverseGeocodeLocation
是异步的,该方法在我的示例中在completionBlock设置p
之前返回一个值。
根据要求,这是我目前的代码。
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) } }) }
我不想采用NSNotificationCenter路由,因为这会增加不必要的开销,而是在completionHandler
闭包内我调用另一个函数并将CLPlacemark
生成的getPlacemarkFromLocation
作为参数传递以保持异步,因为在getPlacemarkFromLocation
之后将调用函数设置函数(应该)接收所需的地标并执行您想要的代码。 希望我所说的有道理。
使用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) } }) }
干杯!
这是关闭对我有用 – 它需要一段时间才能使它工作。 我认为你的问题与不使用正确的初始化程序初始化p有关。 我尝试了一些变化,直到我开始工作:self.placemark = CLPlacemark(placemark:stuff [0] as CLPlacemark)
geocoder.reverseGeocodeLocation(newLocation, completionHandler: {(stuff, error)->Void in if error { println("reverse geodcode fail: \(error.localizedDescription)") return } if stuff.count > 0 { self.placemark = CLPlacemark(placemark: stuff[0] as CLPlacemark) self.addressLabel.text = String(format:"%@ %@\n%@ %@ %@\n%@", self.placemark.subThoroughfare ? self.placemark.subThoroughfare : "" , self.placemark.thoroughfare ? self.placemark.thoroughfare : "", self.placemark.locality ? self.placemark.locality : "", self.placemark.postalCode ? self.placemark.postalCode : "", self.placemark.administrativeArea ? self.placemark.administrativeArea : "", self.placemark.country ? self.placemark.country : "") } else { println("No Placemarks!") return } })
编辑:
更好地回答了自己的答案。
编辑:这不起作用。 关闭之外的值为零 – 请参阅下面的评论
你的p是nil,因为闭包在初始化为引用之前捕获它。 要获得所需的行为,您需要使用非可选值,例如var p:CLPlacemark!。
下面是我用来测试我的猜想的代码:
func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) { var g = CLGeocoder() var p:CLPlacemark? let mynil = "empty" g.reverseGeocodeLocation(newLocation, completionHandler: { (placemarks, error) in let pm = placemarks as? CLPlacemark[] if (pm && pm?.count > 0){ // p = CLPlacemark() p = CLPlacemark(placemark: pm?[0] as CLPlacemark) println("Inside what is in p: \(p?.country ? p?.country : mynil)") } }) println("Outside what is in p: \(p?.country ? p?.country : mynil)") }
这是控制台日志:
按下Pushit < - 按钮开始捕获位置
外面的东西是p:空的
在p:美国的内部
外面的东西是p:空的
在p:美国的内部
外面的东西是p:空…
这个派对迟到了,但看起来你需要(ed)做一些关于异步的东西。 这么说,你现在可能已经学会了。
你的代码的基本问题是在函数返回后正在设置p(你的地标),所以它只是丢失了 – 你不能使用函数来返回带异步的值。 使用完成闭包,代码在到达时(异步)传递地标并调用闭包 – 注意函数现在什么都不返回。
func getPlacemarkFromLocation(_ location: CLLocation, completion: ((CLPlacemark?) -> ())) { CLGeocoder().reverseGeocodeLocation(location, completionHandler: { (placemarks, error) in // use optional chaining to safely return a value or nil // also using .first rather than checking the count & getting placemarks[0] - // if the count is zero, will just give you nil // probably a good idea to check for errors too completion(placemarks?.first) }) }
使用 –
getPlacemarkFromLocation(myLocation, completion: { (placemark) in // do something with the placemark here })
我实际上并没有把它放到Xcode中,但看起来不错……
由于种种原因,你的东西不起作用。 这是我在没有实际查看function的情况下修复的部分:
class func getPlacemarkFromLocation(location:CLLocation)->CLPlacemark?{ var g = CLGeocoder() var p:CLPlacemark? g.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) in let pm = placemarks! if (pm.count > 0){ p = placemarks![0] } }) return p }
- 将contentMode设置为UIViewContentModeScaleAspectFit时,如何设置UIImageView左alignment或右alignment?
- find设备的相机分辨率的方法iOS
- 如何在技术面试中提问
- 是否有可能与UICollectionViewCells使用IBDesignable并生活呈现在故事板?
- 缩小您的.IPA尺寸:EP。 2 —减小PNG图像的大小
- 存储在“string”中的对象的潜在泄漏
- UILabel,UIFont和UTF-8三angular形
- 加载Apple Pay送货地址No Street
- WatchOS 5-Swift上iPhone和Apple Watch之间的通信,反之亦然-第1部分