使用 Firebase 的 Swift 完成处理程序

Posted

技术标签:

【中文标题】使用 Firebase 的 Swift 完成处理程序【英文标题】:Swift completion handler with Firebase 【发布时间】:2018-10-24 15:35:07 【问题描述】:

我正在尝试通过调用以下函数从子节点“PlayerInPool”从 Firebase 获取“玩家”列表

func getPlayersInPool(completion: @escaping (_ success: Bool) -> Void) 

    self.handle = self.poolPlayersRef.child(self.pID)observe(.value, with:  snapshot in     

            // Calling the second function
            self.loadPlayersInPool(/*items: items,*/ snapshot: snapshot)  (success) -> Void in

                if success 

                    print("Players Array Count = ", self.players.count)

                    for j in 0 ..< self.players.count 

                        print(self.players[j].description)

                    
                    //
                    //self.actionController.reloadData()
                    //
                    completion(true)

                

            

    )  (error) in

        print(error.localizedDescription)

    


从上述函数调用的第二个函数:

func loadPlayersInPool(/*items: [String],*/ snapshot: DataSnapshot, completion: @escaping (_ success: Bool) -> Void) 

    var items: [String] = []

    for item in snapshot.children 

        let user = (item as! DataSnapshot).key

        self.userRef.child(user).child("username").observeSingleEvent(of: .value, with:  (snapshot) in

            let username = snapshot.value

            items.append(username! as! String)

        )

    

    self.players = items

    // ISSUE HERE THE PLAYER.COUNT IS ALWAYS ZERO (0)!!!!!!!!!
    for j in 0 ..< players.count 

        print(players[j]description)

    

    completion(true)


问题是播放器数组计数始终为零 (0)!?所以我不确定我是否正确使用了完成处理程序?

【问题讨论】:

【参考方案1】:

observeSingleEvent 调用从服务器加载数据,因此是异步发生的。这意味着您的items.append(username! as! String) 在您调用completion(true) 之后 运行。

获得所需行为的一种简单方法是使用简单的计数器检查是否已加载所有用户名:

func loadPlayersInPool(/*items: [String],*/ snapshot: DataSnapshot, completion: @escaping (_ success: Bool) -> Void) 

    var items: [String] = []

    let loadedCount = 0
    for item in snapshot.children 

        let user = (item as! DataSnapshot).key

        self.userRef.child(user).child("username").observeSingleEvent(of: .value, with:  (snapshot) in

            let username = snapshot.value

            items.append(username! as! String)

            loadedCount++
            if loadedCount == snapshot.childrenCount 
                self.players = items

                for j in 0 ..< players.count 
                    print(players[j]description)
                

                completion(true)
            

        )

    

【讨论】:

以上是关于使用 Firebase 的 Swift 完成处理程序的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 和 Swift:异步调用、完成处理程序

Swift 中的完成处理程序 Firebase 观察者

Firebase Swift 3 完成处理程序 Bool

函数没有返回,Swift Firebase

Swift,带有完成处理程序的网络调用不起作用

等待循环完成,DispatchGroup 使用 Swift 从 firebase 获取数据