如何等到 CLGeocoder 完成工作
Posted
技术标签:
【中文标题】如何等到 CLGeocoder 完成工作【英文标题】:How to wait until CLGeocoder finish its work 【发布时间】:2021-08-30 19:51:01 【问题描述】:我有以下来自 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 变量获得值(函数完成)。我试图将函数调用放入同步调度队列,但没有帮助。 感谢您的任何建议。
【问题讨论】:
不要问,要告诉。意思是:不要等待,通知。请搜索completion handler 【参考方案1】:我愿意:
使用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
【讨论】:
【参考方案2】:是的,完成处理程序将成为您的朋友:
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.
【讨论】:
谢谢你,Brendan C。它现在可以完美运行了。以上是关于如何等到 CLGeocoder 完成工作的主要内容,如果未能解决你的问题,请参考以下文章