无法比较 didUpdateLocations 中的 Firebase latitude/longitude 值
Cannot compare Firebase latitude/longitude values in didUpdateLocations
我正在处理一个关于从 Firebase 获取数据并在我的代码中的其他地方使用该数据的简单问题。下面,我有一个函数可以检索某个位置的纬度和经度,并将它们存储在两个变量 locationLat
和 locationLong
中,这些变量已定义且初始设置为 0.0。我在viewDidLoad
中调用这个函数。
然后在 didUpdateLocations
中访问保存纬度和经度的两个变量,以将用户的位置与从 Firebase 获取的值的纬度和经度进行比较。
我的问题:didUpdateLocations
中的 if 条件不会一直有效,当它无效时,纬度和经度打印 0.0 或 nil 并且它不会 运行 if 语句.
我知道 observeSingleEvent 本质上是异步的,但我不确定在我的代码中如何正确使用 Firebase 数据,尤其是在 didUpdateLocations
委托函数中。任何建议都会很棒。
下面是与此问题相关的两个函数。第一个是我的函数,它从 Firebase 检索纬度和经度。第二个函数是我的 didUpdateLocations
函数,我的错误发生在该函数中。
func getLocationCoordinates() {
let ref = Database.database().reference().child("map").child(self.titleString)
ref.observeSingleEvent(of: .value) { (snapshot) in
let nameSnapshots = snapshot.childSnapshot(forPath: "title")
let val = nameSnapshots.value as! String
if self.locationName.text == val {
let latitude = snapshot.childSnapshot(forPath: "latitude")
let longitude = snapshot.childSnapshot(forPath: "longitude")
let latValue = latitude.value as! CLLocationDegrees
let lonValue = longitude.value as! CLLocationDegrees
self.locationLat = latValue
self.locationLong = lonValue
}
}
}
这里是 didUpdateLocations
函数
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.desiredAccuracy = kCLLocationAccuracyBest
let userLocation :CLLocation = locations[0] as CLLocation
let locationAddress: CLLocation = CLLocation(latitude: locationLat, longitude: locationLong)
print("loc latitude = \(locationAddress.coordinate.latitude)")
print("loc longitude = \(locationAddress.coordinate.longitude)")
let distanceFrom : CLLocationDistance = userLocation.distance(from: locationAddress)
if 300 >= distanceFrom {
checkInOutlet.isEnabled = true
print("we are here")
} else {
checkInOutlet.isEnabled = false
print("not here yet")
}
locationManager.stopUpdatingLocation()
}
由于您的 getLocationCoordinates
和 didUpdateLocations
是 async
调用,您需要等到 getLocationCoordinates
给出来自 firebase 服务器的结果并将 return 值用于didUpdateLocations
方法。
为此,您可以使用 completion
闭包。检查下面的示例代码:
func getLocationCoordinates(completion: @escaping (_ lat: CLLocationDegrees, _ lon: CLLocationDegrees)->()) {
let ref = Database.database().reference().child("map").child(self.titleString)
ref.observeSingleEvent(of: .value) { (snapshot) in
let nameSnapshots = snapshot.childSnapshot(forPath: "title")
let val = nameSnapshots.value as! String
if self.locationName.text == val {
let latitude = snapshot.childSnapshot(forPath: "latitude")
let longitude = snapshot.childSnapshot(forPath: "longitude")
let latValue = latitude.value as! CLLocationDegrees
let lonValue = longitude.value as! CLLocationDegrees
self.locationLat = latValue
self.locationLong = lonValue
completion(latValue, lonValue) //this will return your data
}
}
}
我已经用 completion
回调修改了你的 getLocationCoordinates
并且 completion
会在它从 firebase 服务器和 return lat
和 lon
来自该调用的值。
现在您需要在 didUpdateLocations
方法中使用它,如下所示:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.desiredAccuracy = kCLLocationAccuracyBest
let userLocation :CLLocation = locations[0] as CLLocation
//call your method like this
getLocationCoordinates { (lat, lon) -> () in
//use lat and lon which returned by above method
let locationAddress: CLLocation = CLLocation(latitude: lat, longitude: lon)
print("loc latitude = \(locationAddress.coordinate.latitude)")
print("loc longitude = \(locationAddress.coordinate.longitude)")
let distanceFrom : CLLocationDistance = userLocation.distance(from: locationAddress)
if 300 >= distanceFrom {
self.checkInOutlet.isEnabled = true
print("we are here")
} else {
self.checkInOutlet.isEnabled = false
print("not here yet")
}
self.locationManager.stopUpdatingLocation()
}
}
我正在处理一个关于从 Firebase 获取数据并在我的代码中的其他地方使用该数据的简单问题。下面,我有一个函数可以检索某个位置的纬度和经度,并将它们存储在两个变量 locationLat
和 locationLong
中,这些变量已定义且初始设置为 0.0。我在viewDidLoad
中调用这个函数。
然后在 didUpdateLocations
中访问保存纬度和经度的两个变量,以将用户的位置与从 Firebase 获取的值的纬度和经度进行比较。
我的问题:didUpdateLocations
中的 if 条件不会一直有效,当它无效时,纬度和经度打印 0.0 或 nil 并且它不会 运行 if 语句.
我知道 observeSingleEvent 本质上是异步的,但我不确定在我的代码中如何正确使用 Firebase 数据,尤其是在 didUpdateLocations
委托函数中。任何建议都会很棒。
下面是与此问题相关的两个函数。第一个是我的函数,它从 Firebase 检索纬度和经度。第二个函数是我的 didUpdateLocations
函数,我的错误发生在该函数中。
func getLocationCoordinates() {
let ref = Database.database().reference().child("map").child(self.titleString)
ref.observeSingleEvent(of: .value) { (snapshot) in
let nameSnapshots = snapshot.childSnapshot(forPath: "title")
let val = nameSnapshots.value as! String
if self.locationName.text == val {
let latitude = snapshot.childSnapshot(forPath: "latitude")
let longitude = snapshot.childSnapshot(forPath: "longitude")
let latValue = latitude.value as! CLLocationDegrees
let lonValue = longitude.value as! CLLocationDegrees
self.locationLat = latValue
self.locationLong = lonValue
}
}
}
这里是 didUpdateLocations
函数
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.desiredAccuracy = kCLLocationAccuracyBest
let userLocation :CLLocation = locations[0] as CLLocation
let locationAddress: CLLocation = CLLocation(latitude: locationLat, longitude: locationLong)
print("loc latitude = \(locationAddress.coordinate.latitude)")
print("loc longitude = \(locationAddress.coordinate.longitude)")
let distanceFrom : CLLocationDistance = userLocation.distance(from: locationAddress)
if 300 >= distanceFrom {
checkInOutlet.isEnabled = true
print("we are here")
} else {
checkInOutlet.isEnabled = false
print("not here yet")
}
locationManager.stopUpdatingLocation()
}
由于您的 getLocationCoordinates
和 didUpdateLocations
是 async
调用,您需要等到 getLocationCoordinates
给出来自 firebase 服务器的结果并将 return 值用于didUpdateLocations
方法。
为此,您可以使用 completion
闭包。检查下面的示例代码:
func getLocationCoordinates(completion: @escaping (_ lat: CLLocationDegrees, _ lon: CLLocationDegrees)->()) {
let ref = Database.database().reference().child("map").child(self.titleString)
ref.observeSingleEvent(of: .value) { (snapshot) in
let nameSnapshots = snapshot.childSnapshot(forPath: "title")
let val = nameSnapshots.value as! String
if self.locationName.text == val {
let latitude = snapshot.childSnapshot(forPath: "latitude")
let longitude = snapshot.childSnapshot(forPath: "longitude")
let latValue = latitude.value as! CLLocationDegrees
let lonValue = longitude.value as! CLLocationDegrees
self.locationLat = latValue
self.locationLong = lonValue
completion(latValue, lonValue) //this will return your data
}
}
}
我已经用 completion
回调修改了你的 getLocationCoordinates
并且 completion
会在它从 firebase 服务器和 return lat
和 lon
来自该调用的值。
现在您需要在 didUpdateLocations
方法中使用它,如下所示:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.desiredAccuracy = kCLLocationAccuracyBest
let userLocation :CLLocation = locations[0] as CLLocation
//call your method like this
getLocationCoordinates { (lat, lon) -> () in
//use lat and lon which returned by above method
let locationAddress: CLLocation = CLLocation(latitude: lat, longitude: lon)
print("loc latitude = \(locationAddress.coordinate.latitude)")
print("loc longitude = \(locationAddress.coordinate.longitude)")
let distanceFrom : CLLocationDistance = userLocation.distance(from: locationAddress)
if 300 >= distanceFrom {
self.checkInOutlet.isEnabled = true
print("we are here")
} else {
self.checkInOutlet.isEnabled = false
print("not here yet")
}
self.locationManager.stopUpdatingLocation()
}
}