Arrays 如何使用快照侦听器从函数返回注释数组?
我有一个在Cloud Firestore中监听实时更新的功能:Arrays 如何使用快照侦听器从函数返回注释数组?,arrays,swift,google-cloud-firestore,swiftui,mapkitannotation,Arrays,Swift,Google Cloud Firestore,Swiftui,Mapkitannotation,我有一个在Cloud Firestore中监听实时更新的功能: func getAnnotations() { FirestoreReferenceManager.referenceForAnnotations().addSnapshotListener { (querySnapshot, err) in guard (querySnapshot?.documents) != nil else {
func getAnnotations() {
FirestoreReferenceManager.referenceForAnnotations().addSnapshotListener { (querySnapshot, err) in
guard (querySnapshot?.documents) != nil
else {
print("No documents")
return
}
let exampleAnnotation = MKPointAnnotation()
exampleAnnotation.coordinate = CLLocationCoordinate2D(latitude: CLLocationDegrees(51.5074), longitude: CLLocationDegrees(0.1278))
let exampleSecondAnnotation = MKPointAnnotation()
exampleSecondAnnotation.coordinate = CLLocationCoordinate2D(latitude: CLLocationDegrees(51.5074), longitude: CLLocationDegrees(0.1278))
var annotationArray = [exampleAnnotation, exampleSecondAnnotation]
for document in querySnapshot!.documents {
let lat = document.get("latitude") as! String
let lon = document.get("longitude") as! String
print(lat, lon)
let latitude = Double(lat)
let longitude = Double(lon)
let truecoordinate : CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: latitude ?? 0, longitude: longitude ?? 0)
let annotation = MKPointAnnotation()
annotation.coordinate = truecoordinate
annotationArray.append(annotation)
}
//return annotationArray
}
}
注释行导致以下错误:
“void函数中意外的非void返回值”
我想返回annotationArray。。。
任何解决方案?您不能从完成或异步代码返回代码,请注意,您可以调用并侦听
irestoreReferenceManager.ReferenceForNotations().addSnapshotListener
您需要使用补全:
func getAnnotations(completionHandler: @escaping (([MKPointAnnotation]) -> Void)) {
.... you code
.... end of loop
completionHandler(annotationArray)
}
我建议阅读和学习Swift中的补全和闭包:
由于任务是异步的,您需要的是一个完成处理程序。您可以返回一个
Result
对象,并对其稍微感兴趣,或者在出现错误时返回nil
,在没有结果时返回空数组。两者都能很好地完成工作。您还应该避免强制展开文档字段,因为这可能会使应用程序完全崩溃;始终安全地打开可选包装
func getAnnotations(completion: @escaping (_ annotations: [MKPointAnnotation]?) -> Void) {
FirestoreReferenceManager.referenceForAnnotations().addSnapshotListener { (querySnapshot, err) in
guard let snapshot = querySnapshot else {
if let err = err {
print(err)
}
completion(nil) // return nil if error
return
}
guard !snapshot.isEmpty else {
completion([]) // return empty if no documents
return
}
var annotations = [MKPointAnnotation]()
for doc in snapshot.documents {
if let lat = doc.get("latitude") as? String,
let lon = doc.get("longitude") as? String,
let latitude = Double(lat),
let longitude = Double(lon) {
let coord = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
let annotation = MKPointAnnotation()
annotation.coordinate = coord
annotations.append(annotation)
}
}
completion(annotations) // return array
}
}
用法
getAnnotations { (annotations) in
if let annotations = annotations {
// add to map
} else {
// handle error
}
}
也就是说,我会将坐标存储在Firestore中,作为
地质点
,然后简单地将它们转换为CLLocationCoordinate2D
,而不是将它们存储为字符串并将它们转换为双精度,然后再转换为坐标。这是不干净的、不必要的,并且更容易出错。您不能从该函数返回——它是异步的,这意味着它不会立即返回。转而考虑使用回调函数。