Firebase GeoFire 关闭
Firebase GeoFire closure
我正在尝试使用 Firebase GeoFire,但关闭总是让我失望。 Firebase 在其文档中提供了这个示例代码片段
// After all callbacks have executed, matchingDocs contains the result. Note that this
// sample does not demonstrate how to wait on all callbacks to complete.
for query in queries {
query.getDocuments(completion: getDocumentsCompletion)
}
不幸的是,它并没有展示我所需要的...
我希望它在预设的时间间隔内触发,所以我有这样的安排:
locationTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(getLocations), userInfo: nil, repeats: true)
那么我的代码与示例差不多:
var matchingDocs = [QueryDocumentSnapshot]()
@objc func getLocations() {
let center = CLLocationCoordinate2D(latitude: lat, longitude: lon)
let radiusInM: Double = 10000
// Each item in 'bounds' represents a startAt/endAt pair. We have to issue
// a separate query for each pair. There can be up to 9 pairs of bounds
// depending on overlap, but in most cases there are 4.
let queryBounds = GFUtils.queryBounds(forLocation: center,
withRadius: radiusInM)
let queries = queryBounds.map { bound -> Query in
return db.collection("geopoints")
.order(by: "geohash")
}
// Collect all the query results together into a single list
func getDocumentsCompletion(snapshot: QuerySnapshot?, error: Error?) -> () {
guard let documents = snapshot?.documents else {
print("Unable to fetch snapshot data. \(String(describing: error))")
return
}
for document in documents {
let lat = document.data()["lat"] as? Double ?? 0
let lng = document.data()["lng"] as? Double ?? 0
let coordinates = CLLocation(latitude: lat, longitude: lng)
let centerPoint = CLLocation(latitude: center.latitude, longitude: center.longitude)
// We have to filter out a few false positives due to GeoHash accuracy, but most will match
let distance = GFUtils.distance(from: centerPoint, to: coordinates)
if distance <= radiusInM {
matchingDocs.append(document)
}
}
}
// After all callbacks have executed, matchingDocs contains the result. Note that this
// sample does not demonstrate how to wait on all callbacks to complete.
for query in queries {
query.getDocuments(completion: getDocumentsCompletion)
}
}
}
等待回调完成并使用包含所有地理点的 matchingDocs 继续执行 getLocations() 函数之外的程序的正确方法是什么?感谢您的任何建议。
这是我的解决方案。只有在所有查询返回后才会调用完成的函数 allDone()。
// button press to read data from Firebase
@IBAction func getData(_ sender: Any) {
getLocations(completion: {
// code here to process all query results
})
}
func getLocations(completion: @escaping () -> Void) {
let center = CLLocationCoordinate2D(latitude: lat, longitude: lon)
let radiusInM: Double = 10000
var queriesFinished = 0
// Each item in 'bounds' represents a startAt/endAt pair. We have to issue
// a separate query for each pair. There can be up to 9 pairs of bounds
// depending on overlap, but in most cases there are 4.
let queryBounds = GFUtils.queryBounds(forLocation: center,
withRadius: radiusInM)
let queries = queryBounds.map { bound -> Query in
return db.collection("geopoints")
.order(by: "geohash")
}
let numOfQueries = queries.count
// Collect all the query results together into a single list
func getDocumentsCompletion(snapshot: QuerySnapshot?, error: Error?) -> () {
guard let documents = snapshot?.documents else {
print("Unable to fetch snapshot data. \(String(describing: error))")
return
}
for document in documents {
let lat = document.data()["lat"] as? Double ?? 0
let lng = document.data()["lng"] as? Double ?? 0
let coordinates = CLLocation(latitude: lat, longitude: lng)
let centerPoint = CLLocation(latitude: center.latitude, longitude: center.longitude)
// We have to filter out a few false positives due to GeoHash accuracy, but most will match
let distance = GFUtils.distance(from: centerPoint, to: coordinates)
if distance <= radiusInM {
matchingDocs.append(document)
}
}
queriesFinished += 1
allDone()
}
// After all callbacks have executed, matchingDocs contains the result. Note that this
// sample does not demonstrate how to wait on all callbacks to complete.
for query in queries {
query.getDocuments(completion:getDocumentsCompletion)
}
func allDone() {
if queriesFinished == numOfQueries {
completion()
}
}
}
我在读到 async/await 可能是更好的方法,但我没有让它发挥作用。
我正在尝试使用 Firebase GeoFire,但关闭总是让我失望。 Firebase 在其文档中提供了这个示例代码片段
// After all callbacks have executed, matchingDocs contains the result. Note that this
// sample does not demonstrate how to wait on all callbacks to complete.
for query in queries {
query.getDocuments(completion: getDocumentsCompletion)
}
不幸的是,它并没有展示我所需要的...
我希望它在预设的时间间隔内触发,所以我有这样的安排:
locationTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(getLocations), userInfo: nil, repeats: true)
那么我的代码与示例差不多:
var matchingDocs = [QueryDocumentSnapshot]()
@objc func getLocations() {
let center = CLLocationCoordinate2D(latitude: lat, longitude: lon)
let radiusInM: Double = 10000
// Each item in 'bounds' represents a startAt/endAt pair. We have to issue
// a separate query for each pair. There can be up to 9 pairs of bounds
// depending on overlap, but in most cases there are 4.
let queryBounds = GFUtils.queryBounds(forLocation: center,
withRadius: radiusInM)
let queries = queryBounds.map { bound -> Query in
return db.collection("geopoints")
.order(by: "geohash")
}
// Collect all the query results together into a single list
func getDocumentsCompletion(snapshot: QuerySnapshot?, error: Error?) -> () {
guard let documents = snapshot?.documents else {
print("Unable to fetch snapshot data. \(String(describing: error))")
return
}
for document in documents {
let lat = document.data()["lat"] as? Double ?? 0
let lng = document.data()["lng"] as? Double ?? 0
let coordinates = CLLocation(latitude: lat, longitude: lng)
let centerPoint = CLLocation(latitude: center.latitude, longitude: center.longitude)
// We have to filter out a few false positives due to GeoHash accuracy, but most will match
let distance = GFUtils.distance(from: centerPoint, to: coordinates)
if distance <= radiusInM {
matchingDocs.append(document)
}
}
}
// After all callbacks have executed, matchingDocs contains the result. Note that this
// sample does not demonstrate how to wait on all callbacks to complete.
for query in queries {
query.getDocuments(completion: getDocumentsCompletion)
}
}
}
等待回调完成并使用包含所有地理点的 matchingDocs 继续执行 getLocations() 函数之外的程序的正确方法是什么?感谢您的任何建议。
这是我的解决方案。只有在所有查询返回后才会调用完成的函数 allDone()。
// button press to read data from Firebase
@IBAction func getData(_ sender: Any) {
getLocations(completion: {
// code here to process all query results
})
}
func getLocations(completion: @escaping () -> Void) {
let center = CLLocationCoordinate2D(latitude: lat, longitude: lon)
let radiusInM: Double = 10000
var queriesFinished = 0
// Each item in 'bounds' represents a startAt/endAt pair. We have to issue
// a separate query for each pair. There can be up to 9 pairs of bounds
// depending on overlap, but in most cases there are 4.
let queryBounds = GFUtils.queryBounds(forLocation: center,
withRadius: radiusInM)
let queries = queryBounds.map { bound -> Query in
return db.collection("geopoints")
.order(by: "geohash")
}
let numOfQueries = queries.count
// Collect all the query results together into a single list
func getDocumentsCompletion(snapshot: QuerySnapshot?, error: Error?) -> () {
guard let documents = snapshot?.documents else {
print("Unable to fetch snapshot data. \(String(describing: error))")
return
}
for document in documents {
let lat = document.data()["lat"] as? Double ?? 0
let lng = document.data()["lng"] as? Double ?? 0
let coordinates = CLLocation(latitude: lat, longitude: lng)
let centerPoint = CLLocation(latitude: center.latitude, longitude: center.longitude)
// We have to filter out a few false positives due to GeoHash accuracy, but most will match
let distance = GFUtils.distance(from: centerPoint, to: coordinates)
if distance <= radiusInM {
matchingDocs.append(document)
}
}
queriesFinished += 1
allDone()
}
// After all callbacks have executed, matchingDocs contains the result. Note that this
// sample does not demonstrate how to wait on all callbacks to complete.
for query in queries {
query.getDocuments(completion:getDocumentsCompletion)
}
func allDone() {
if queriesFinished == numOfQueries {
completion()
}
}
}
我在读到 async/await 可能是更好的方法,但我没有让它发挥作用。