作为对用户操作的响应,我想将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")
}
但是,我似乎无法正确理解
对于如何执行此操作的任何建议将不胜感激。
答案 0 :(得分:2)
您只需要在方法中添加完成处理程序,并在调用完成时返回第一个地标:
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,拉各斯,里约热内卢 Janeiro-RJ,22011-040,巴西@ <-22.96345100,-43.19824200> +/- 100.00m,区域CLCircularRegion(标识:'<-22.96345100,-43.19824200>半径141.83', 中心:<-22.96345100,-43.19824200>,半径: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拉各斯里约热内卢RJ 22011-040巴西