Внутри базы данных ссылка GeoFire каждого местоположения userId имеет "g"
дочерний элемент и "l"
дочерний элемент:
@geoLocations
|
@--abc123xyz456 // userId
|
@--g: "dr72xyz25abc" // geoFire id for this user's location in geoFire
|
@--l
|--0: 40.870431300779900 // latitude
|--1: -73.090007211987188 // longitude
Вот изображение фактического макета базы данных
Я понятия не имею, что означает "g"
, но я предполагаю, что "l"
обозначает местоположение, потому что оно имеет тип CLLocation
, как указано в аргументах .observe(.keyEntered, with: { (key: String!, location: CLLocation!)
,
Внутри базы данных ключ 0
и 1
хранятся как snapshot.value
массива либо CLLocationDegrees
, либо Double
.
Для получения latitude
и longitude
Я использовал let arr = snapshot.value as? [CLLocationDegrees]
, но let arr = snapshot.value as? [Double]
также работал.
Создайте ссылку, у которой есть дочернее имя независимо от того, какое имя у вашей ссылки geoLocations есть>, затем добавьте дочерний элемент userId>, затем добавьтеДитя "L" для местоположения ребенка.
Запустите observeSingleEvent(of: .value
и при вызове приведите snapshot.value
в виде массива [CLLocationDegrees]
// *** if using CLLocationDegrees be to import CoreLocation ***
import CoreLocation
let geoLocationsRef = Database.database().reference()
.child("geoLocations") // name of my geoRef in Firebase
.child("abc123xyz456") // the userId I'm observing
.child("l") // the "l" is the child to observe
geoLocationsRef.observeSingleEvent(of: .value, with: { (snapshot) in
if !snapshot.exists() { return }
guard let arr = snapshot.value as? [CLLocationDegrees] else { return }
if arr.count > 1 {
let latitude = arr[0]
print(latitude)
let longitude = arr[1]
print(longitude)
// do whatever with the latitude and longitude
}
})
Вот ответ на мой вопрос с использованием dispatchGroup ():
func queryLocationOfSubsetOfUsersInRadius() {
let dispatchGroup = DispatchGroup()
for user in subsetOfUsersInRadius {
dispatchGroup.enter()
let userId = user.userId
let geoLocationsRef = Database.database().reference()
.child("geoLocations")
.child(userId)
.child("l")
geoLocationsRef.observeSingleEvent(of: .value, with: { (snapshot) in
// this user may have deleted their location
if !snapshot.exists() {
dispatchGroup.leave()
return
}
guard let arr = snapshot.value as? [CLLocationDegrees] else {
dispatchGroup.leave()
return
}
if arr.count > 1 {
let latitude = arr[0]
print(latitude)
let longitude = arr[1]
print(longitude)
// do whatever with the latitude and longitude
}
dispatchGroup.leave()
})
}
dispatchGroup.notify(queue: .global(qos: .background)) {
// now animate the annotation from the user's inital old location (if they moved) on the mapView to their new location on the mapView. It's supposed to look like Uber's cars moving. Happens on main thread
}
}