如何等到 CLGeocoder 完成它的工作
How to wait until CLGeocoder finish its work
我有以下函数根据 GPS 坐标对地址进行地理编码
private func getAddressFromLocation(forLocation: CLLocationCoordinate2D) {
let geoCoder = CLGeocoder()
geoCoder.reverseGeocodeLocation(CLLocation(latitude: forLocation.latitude, longitude: forLocation.longitude), completionHandler: {(places, error) in
guard error == nil else {
return
}
let place: CLPlacemark = places!.first!
var address: [String] = []
if place.country != nil { address.append(place.country!) }
if place.postalCode != nil { address.append(place.postalCode!) }
if place.locality != nil { address.append(place.locality!) }
if place.thoroughfare != nil { address.append(place.thoroughfare!) }
self.fullAddress = address.joined(separator: ",")
})
}
函数是从我的应用程序的另一部分调用的,我想知道如何确保程序会等到 fullAddress 变量获得值(函数完成)。我试图将函数调用放入同步调度队列,但没有帮助。
感谢您的任何建议。
是的,完成处理程序将成为您的朋友:
typealias CompletionHandler = (_ success:Bool) -> Void
private func getAddressFromLocation(forLocation: CLLocationCoordinate2D, completionHandler: @escaping CompletionHandler) {
let geoCoder = CLGeocoder()
geoCoder.reverseGeocodeLocation(CLLocation(latitude: forLocation.latitude, longitude: forLocation.longitude), completionHandler: {(places, error) in
guard error == nil else {
completionHandler(false)
return
}
let place: CLPlacemark = places!.first!
var address: [String] = []
if place.country != nil { address.append(place.country!) }
if place.postalCode != nil { address.append(place.postalCode!) }
if place.locality != nil { address.append(place.locality!) }
if place.thoroughfare != nil { address.append(place.thoroughfare!) }
print("address: \(address.joined(separator: ","))")
completionHandler(true)
})
}
你可以这样称呼:
getAddressFromLocation(forLocation: CLLocationCoordinate2D()) { success in
if success {
//once address is fetched, this will be triggered.
}
}
我会:
- 使用
Result
类型的完成处理程序;
- 将 UI 的更新与反向地理编码分离;
- 使用
Contacts
框架中的CNPostalAddressFormatter
格式化地址;
例如
enum GeocodeError: Error {
case notFound
}
let geocoder = CLGeocoder()
func getAddress(for coordinate: CLLocationCoordinate2D, completion: @escaping (Result<String, Error>) -> Void) {
let location = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
geocoder.reverseGeocodeLocation(location) { places, error in
guard error == nil, let address = places?.first?.postalAddress else {
completion(.failure(error ?? GeocodeError.notFound))
return
}
let formatter = CNPostalAddressFormatter()
let string = formatter.string(from: address)
.components(separatedBy: "\n")
.joined(separator: ", ")
completion(.success(string))
}
}
然后这样称呼它:
getAddress(for: coordinate) { result in
switch result {
case .failure(let error): // update UI to report error, if any
case .success(let address): // update UI to show address
}
}
我有以下函数根据 GPS 坐标对地址进行地理编码
private func getAddressFromLocation(forLocation: CLLocationCoordinate2D) {
let geoCoder = CLGeocoder()
geoCoder.reverseGeocodeLocation(CLLocation(latitude: forLocation.latitude, longitude: forLocation.longitude), completionHandler: {(places, error) in
guard error == nil else {
return
}
let place: CLPlacemark = places!.first!
var address: [String] = []
if place.country != nil { address.append(place.country!) }
if place.postalCode != nil { address.append(place.postalCode!) }
if place.locality != nil { address.append(place.locality!) }
if place.thoroughfare != nil { address.append(place.thoroughfare!) }
self.fullAddress = address.joined(separator: ",")
})
}
函数是从我的应用程序的另一部分调用的,我想知道如何确保程序会等到 fullAddress 变量获得值(函数完成)。我试图将函数调用放入同步调度队列,但没有帮助。 感谢您的任何建议。
是的,完成处理程序将成为您的朋友:
typealias CompletionHandler = (_ success:Bool) -> Void
private func getAddressFromLocation(forLocation: CLLocationCoordinate2D, completionHandler: @escaping CompletionHandler) {
let geoCoder = CLGeocoder()
geoCoder.reverseGeocodeLocation(CLLocation(latitude: forLocation.latitude, longitude: forLocation.longitude), completionHandler: {(places, error) in
guard error == nil else {
completionHandler(false)
return
}
let place: CLPlacemark = places!.first!
var address: [String] = []
if place.country != nil { address.append(place.country!) }
if place.postalCode != nil { address.append(place.postalCode!) }
if place.locality != nil { address.append(place.locality!) }
if place.thoroughfare != nil { address.append(place.thoroughfare!) }
print("address: \(address.joined(separator: ","))")
completionHandler(true)
})
}
你可以这样称呼:
getAddressFromLocation(forLocation: CLLocationCoordinate2D()) { success in
if success {
//once address is fetched, this will be triggered.
}
}
我会:
- 使用
Result
类型的完成处理程序; - 将 UI 的更新与反向地理编码分离;
- 使用
Contacts
框架中的CNPostalAddressFormatter
格式化地址;
例如
enum GeocodeError: Error {
case notFound
}
let geocoder = CLGeocoder()
func getAddress(for coordinate: CLLocationCoordinate2D, completion: @escaping (Result<String, Error>) -> Void) {
let location = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
geocoder.reverseGeocodeLocation(location) { places, error in
guard error == nil, let address = places?.first?.postalAddress else {
completion(.failure(error ?? GeocodeError.notFound))
return
}
let formatter = CNPostalAddressFormatter()
let string = formatter.string(from: address)
.components(separatedBy: "\n")
.joined(separator: ", ")
completion(.success(string))
}
}
然后这样称呼它:
getAddress(for: coordinate) { result in
switch result {
case .failure(let error): // update UI to report error, if any
case .success(let address): // update UI to show address
}
}