Arrays 如何使用快照侦听器从函数返回注释数组?

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 {

我有一个在Cloud Firestore中监听实时更新的功能:

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
,而不是将它们存储为字符串并将它们转换为双精度,然后再转换为坐标。这是不干净的、不必要的,并且更容易出错。

您不能从该函数返回——它是异步的,这意味着它不会立即返回。转而考虑使用回调函数。