- 背景**
我正在尝试构建一个类,它可以轻松地将字符串(如地址)转换为CLLocationCoordinate2D,以备将来使用,并将其保存到数据库中。
我有一个类似下面的类:
final class PublishMapData: ObservableObject {
@Published var userAddressLat: Double = 0.0
@Published var userAddressLong: Double = 0.0
func saveMapData(address: String){
let address = "One Apple Park Way, Cupertino, CA 95014" //simulating the call from a save button for instance
convertAddress(address: address)
print(String(userAddressLat)) //this prints 0.0
print(String(userAddressLong)) //this print 0.0
//{...extra code here...}
//this is where I would be storing the coordinates into something like Firestore for later use
}
func convertAddress(address: String) {
getCoordinate(addressString: address) { (location, error) in
if error != nil {
return
}
DispatchQueue.main.async {
self.userAddressLat = location.latitude
print(self.userAddressLat) //this prints the correct value
self.userAddressLong = location.longitude
print(self.userAddressLong) //this prints the correct value
}
}
}
private func getCoordinate(addressString : String, completionHandler: @escaping(CLLocationCoordinate2D, NSError?) -> Void ) {
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(addressString) { (placemarks, error) in
if error == nil {
if let placemark = placemarks?[0] {
let location = placemark.location!
completionHandler(location.coordinate, nil)
return
}
}
completionHandler(kCLLocationCoordinate2DInvalid, error as NSError?)
}
}
}
由于某种原因,我无法从convertAddress函数中获取lat、long值,从而无法正确存储在@Published变量中。我做错了什么?我仍在学习Swift。提前感谢您的帮助。
2条答案
按热度按时间kiayqfof1#
根据https://developer.apple.com/documentation/corelocation/clgeocoder/1423509-geocodeaddressstring
是一个异步函数,这意味着它的完成处理程序将在稍后的时间点执行,并且被调用的函数将立即返回。
所以当你打电话
它立即返回,调度稍后调用的dispatchQueue闭包。
接下来执行,打印0.0
稍后执行。
wfypjpf42#
@lastbreath感谢您强调
geocodeAddressString(_:completionHandler:)
的异步特性,因此我发现可以使用异步geocodeAddressString调用来代替之前的方法。这在您提供的链接中已注明:
这是固定的代码......要实现将值发送到@Published变量要简单得多。
感谢您帮助我们找到答案。