本文介绍了使用Firebase的Swift完成处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过调用以下函数从子节点"PlayerInPool"中获取Firebase中的玩家"列表

I am trying to get a list of 'players' from Firebase from the child node 'PlayerInPool' by calling the following functions

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)

    }

}

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

Second function called from the above function:

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)!?所以我不确定我是否正确使用了完成处理程序?

The issue is that the player array count is always zero (0)!? So I'm not sure if I am using the completion handler correctly?

推荐答案

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

The observeSingleEvent call loads data from the server, so happens asynchronously. This means that your items.append(username! as! String) runs after your call to completion(true).

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

A simple way to get the behavior you want, is to check if you've loaded all user names by using a simple counter:

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完成处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 18:01