【问题标题】:function returns after changing Firebase observer SWIFT 4更改 Firebase 观察者 SWIFT 4 后函数返回
【发布时间】:2019-07-23 14:26:06
【问题描述】:

我正在重写我的 firebase 函数,将它自己的函数放入从数据库获取数据的实时部分,所以我在引用数据库时从 .observe(.childAdded, with: {(snapshot) in 更改为 .observeSingleEvent(of: .value, with: { (snapshot) in。该函数现在在 guard let data = snapshot.value as? [String :String] else { return } 上返回,而之前不是...... 当快照相同时发生了什么变化?对它的任何解释都会很棒,因为我自己看不到。 非常感谢一如既往。

这里是函数的两个版本:

老观察者:

func displayAlerts(setCompletion: @escaping (Bool) -> ()) {
        self.mapView.removeAnnotations(mapView.annotations)
        MapArray.alertNotificationCoordinatesArray.removeAll()
        self.userAlertNotificationArray.removeAll()
        print("                     MapArray.alertNotificationCoordinatesArray before snapshot is: \(MapArray.alertNotificationCoordinatesArray)")
        print("                     self.userAlertNotificationArray before snapshot is: \(self.userAlertNotificationArray)")

        ref = Database.database().reference()

        databaseHandle = ref?.child("Continent").child("Europe").child("Country").child("Italy").child("Region").child("Emilia-Romagna").child("City").child("Bologna").child("Community").child("Alert Notifications").observe(.childAdded, with: { (snapshot) in


            //            self.mapView.removeAnnotations(self.mapView.annotations) //
            print("         snapshot is: \(snapshot)")
            guard let data = snapshot.value as? [String:String] else { return }
            guard let firebaseKey = snapshot.key as? String else { return }
            //                let date = data!["Date"]
            //                let time = data!["Time"]
            let dataLatitude = data["Latitude"]!
            let dataLongitude = data["Longitude"]!

            let type = data["Description"]!
            let id = Int(data["Id"]!)
            let doubledLatitude = Double(dataLatitude)
            let doubledLongitude = Double(dataLongitude)
            let recombinedCoordinate = CLLocationCoordinate2D(latitude: doubledLatitude!, longitude: doubledLongitude!)

            print("Firebase alerts posts retrieved")

            let userAlertAnnotation = UserAlert(type: type, coordinate: recombinedCoordinate, firebaseKey: firebaseKey, title: type,id: id!)

            self.userAlertNotificationArray.append(userAlertAnnotation)  // array of notifications coming from Firebase
            //            print("userAlertNotificationArray after retrieving from Firebase is : \(self.userAlertNotificationArray)")

            MapArray.alertNotificationCoordinatesArray.append(recombinedCoordinate) // array for checkig alerts on route


            print("                 MapArray.alertNotificationCoordinatesArray after snapshot is: \(MapArray.alertNotificationCoordinatesArray)")
            print("                     self.userAlertNotificationArray after snapshot is: \(self.userAlertNotificationArray)")
            setCompletion(true)
            self.mapView.addAnnotations(self.userAlertNotificationArray)
        })

    }

新观察者:

func displayAlerts(setCompletion: @escaping (Bool) -> ()) {
    print("                     MapArray.alertNotificationCoordinatesArray before newer displayAlert snapshot is: \(MapArray.alertNotificationCoordinatesArray)")
    print("                     self.userAlertNotificationArray before displayAlert snapshot is: \(self.userAlertNotificationArray)")

    if self.userAlertNotificationArray.count == 0 {
       ref = Database.database().reference()

        ref?.child("Continent").child("Europe").child("Country").child("Italy").child("Region").child("Emilia-Romagna").child("City").child("Bologna").child("Community").child("Alert Notifications").observeSingleEvent(of: .value, with: { (snapshot) in


            //            self.mapView.removeAnnotations(self.mapView.annotations) //
            print("         snapshot is: \(snapshot)")
            guard let data = snapshot.value as? [String :Any] else { return }
            guard let firebaseKey = snapshot.key as? String else { return }
            //                let date = data!["Date"]
            //                let time = data!["Time"]
            let dataLatitude = data["Latitude"] as! Double
            let dataLongitude = data["Longitude"] as! Double

            let type = data["Description"] as! String
            let id = Int(data["Id"] as! String)
            let doubledLatitude = Double(dataLatitude)
            let doubledLongitude = Double(dataLongitude)
            let recombinedCoordinate = CLLocationCoordinate2D(latitude: doubledLatitude, longitude: doubledLongitude)

                        print("Firebase alerts posts retrieved")

            let userAlertAnnotation = UserAlert(type: type, coordinate: recombinedCoordinate, firebaseKey: firebaseKey, title: type,id: id!)

            self.userAlertNotificationArray.append(userAlertAnnotation)  // array of notifications coming from Firebase

            MapArray.alertNotificationCoordinatesArray.append(recombinedCoordinate) // array for checkig alerts on route


            print("                 MapArray.alertNotificationCoordinatesArray after newer displayAlert snapshot is: \(MapArray.alertNotificationCoordinatesArray)")
            print("                     self.userAlertNotificationArray after newer displayAlert snapshot is: \(self.userAlertNotificationArray)")
            self.mapView.addAnnotations(self.userAlertNotificationArray)
            setCompletion(true)

        })
    }
}

编辑:

这里是快照的打印结果,以便查看两个版本的结果:

观察SingleEvent 快照:

snapshot is: Snap (Alert Notifications) {
    "-LZtTuFSKMhhXFwyT-7K" =     {
        Description = "Ciclabile chiusa";
        Id = 0;
        Latitude = "44.50139187990401";
        Longitude = "11.33592981426992";
    };
    "-LZtUV8MOxVrvPnEfi4g" =     {
        Description = "Lavori in corso";
        Id = 1;
        Latitude = "44.5013918797401";
        Longitude = "11.335929814371545";
    };
    "-LZtV7sJJrOQjAimszTm" =     {
        Description = "Pericoli sulla ciclabile";
        Id = 2;
        Latitude = "44.50139187974223";
        Longitude = "11.335929814367324";
    };
}

和孩子添加的快照:

snapshot is: Snap (-LZtTuFSKMhhXFwyT-7K) {
    Description = "Ciclabile chiusa";
    Id = 0;
    Latitude = "44.50139187990401";
    Longitude = "11.33592981426992";
}

snapshot is: Snap (-LZtUV8MOxVrvPnEfi4g) {
    Description = "Lavori in corso";
    Id = 1;
    Latitude = "44.5013918797401";
    Longitude = "11.335929814371545";
}

snapshot is: Snap (-LZtV7sJJrOQjAimszTm) {
    Description = "Pericoli sulla ciclabile";
    Id = 2;
    Latitude = "44.50139187974223";
    Longitude = "11.335929814367324";
}

【问题讨论】:

    标签: swift firebase firebase-realtime-database observers


    【解决方案1】:

    改变

    guard let data = snapshot.value as? [String :String] else { return }
    

    guard let data = snapshot.value as? [String :[String:String]] else { return } 
    data.values.forEach {  
        print($0["Latitude"]) 
        print($0["Longitude"])  
    }
    

    【讨论】:

    • 我刚刚尝试过,但出现了一组新错误:在“let id”上我得到Cannot invoke initializer for type 'Int' with an argument list of type '(Any)',在doubleLatitudedoubleLongitude上我得到Cannot invoke initializer for type 'Double' with an argument list of type '(Any)'..
    • 暂时注释下面的所有行,并用print(snapshot.value)检查它是否给出正确的输出并分享它
    • 好吧,我将它们转换为 let dataLatitude = data["Latitude"] as! Stringso 错误消失了,但即使快照有 3 个值,我也会得到一个 nil 错误:
    • `Snap (Alert Notifications) { "-LZtUV8MOxVrvPnEfi4g" = { Description = "Lavori in corso"; Id = 1; Latitude = "44.5013918797401"; Longitude = "11.335929814371545"; }; "-LZtV7sJJrOQjAimszTm" = { Description = "Pericoli sulla ciclabile"; Id = 2; Latitude = "44.50139187974223"; Longitude = "11.335929814367324"; };
    • 所以快照没问题
    【解决方案2】:

    你能举例说明 json 是如何存储在数据库中的吗?与

    .observe(.childAdded, with: {(snapshot) in
    

    您只收到添加的孩子,并且与

    .observeSingleEvent(of: .value, with: { (snapshot) in
    

    你收到整个节点,所以可能节点不是 [String:String] 它可能不止一个项目,所以它应该是 [String:Any] 然后你可以从其中获取每个子节点。

    【讨论】:

    • 我用每个函数的快照更新了我的问题。我不得不说.observeSingleEvent(of: .value, with: { (snapshot) in给我一个快照,而.observe(.childAdded, with: {(snapshot) in给我三个不同的快照,节点中的每个帖子一个。希望它对我在代码中做错的事情有用。谢谢
    【解决方案3】:

    这只是部分答案,但经过多次不同的尝试并在 Sh_Khan 的帮助下,我们必须让它发挥作用。问题出在guard let data = snapshot.value as? [String :Any] else { return } 需要guard let data = snapshot.value as? [String : [String : String] else { return } 的行中。

    所以函数必须写成:

    func displayAlerts(setCompletion: @escaping (Bool) -> ()) {
            print("                     MapArray.alertNotificationCoordinatesArray before displayAlert snapshot is: \(MapArray.alertNotificationCoordinatesArray)")
            print("                     self.userAlertNotificationArray before displayAlert snapshot is: \(self.userAlertNotificationArray)")
    
            if self.userAlertNotificationArray.count == 0 {
               ref = Database.database().reference()
    
                ref?.child("Continent").child("Europe").child("Country").child("Italy").child("Region").child("Emilia-Romagna").child("City").child("Bologna").child("Community").child("Alert Notifications").observeSingleEvent(of: .value, with: { (snapshot) -> Void in
                    print("         snapshot is: \(snapshot)")
                    guard let data = snapshot.value as? [String :[String:String]] else { return }
    
                    guard let firebaseKey = snapshot.key as? String else { return }
    
                    data.values.forEach {
    //                    let firebaseKey = data.keys[]
    
                        let dataLatitude = $0["Latitude"]!
                        let dataLongitude = $0["Longitude"]!
                        let type = $0["Description"]!
                        let id = Int($0["Id"]!)
    
                        print("firebaseKey is:\(firebaseKey)")
                        print("dataLatitude is: \(dataLatitude)")
                        print("dataLongitude is: \(dataLongitude)")
                        print("type is: \(type)")
                        print("id is: \(id)")
                        print("Key is: \(firebaseKey)")
                        print("data is: \(data)")
    
                        let doubledLatitude = Double(dataLatitude)
                        let doubledLongitude = Double(dataLongitude)
                        let recombinedCoordinate = CLLocationCoordinate2D(latitude: doubledLatitude!, longitude: doubledLongitude!)
    
                        let userAlertAnnotation = UserAlert(type: type, coordinate: recombinedCoordinate, firebaseKey: firebaseKey, title: type,id: id!)
                        self.userAlertNotificationArray.append(userAlertAnnotation)  // array of notifications coming from Firebase
                        MapArray.alertNotificationCoordinatesArray.append(recombinedCoordinate)
                    }
    
    
                                print("Firebase alerts posts retrieved")
    
                    print("                 MapArray.alertNotificationCoordinatesArray after  displayAlert snapshot is: \(MapArray.alertNotificationCoordinatesArray)")
                    print("                     self.userAlertNotificationArray after  displayAlert snapshot is: \(self.userAlertNotificationArray)")
                    self.mapView.addAnnotations(self.userAlertNotificationArray)
                    setCompletion(true)
    
                })
            }
        }
    

    现在我要解决两件事。第一:如何获取子键作为guard let firebaseKey = snapshot.key as? String else { return }给我节点的名称而不是行? 第二:我创建的新函数只是为了获得带有.observe(.childAdded, with: { (snapshot) in 的newerAlerts,在将新子节点添加到节点时不会被调用。 我应该问新问题还是继续这里?

    谢谢

    【讨论】:

      猜你喜欢
      • 2018-09-12
      • 2017-03-03
      • 1970-01-01
      • 2018-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-09
      相关资源
      最近更新 更多