Быстрый обработчик завершения с Firebase - PullRequest
0 голосов
/ 24 октября 2018

Я пытаюсь получить список «игроков» из Firebase из дочернего узла «PlayerInPool», вызывая следующие функции

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 Ответ

0 голосов
/ 24 октября 2018

Вызов 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)
            }

        })

    }
}
...