Как вызвать объединение нескольких обработчиков завершения для объединения данных в один новый массив - PullRequest
0 голосов
/ 15 июня 2019

Я застрял на некоторое время, и любые советы будут с благодарностью. Я создаю приложение, которое использует базу данных Firebase, и я создал 5 классов, которые содержат разные данные в Firebase. Я создаю табличное представление, которое должно отображать информацию от каждого из 5 классов (имя профиля, изображение, затем информацию о лиге и информацию о результатах). Итак, в моем новом классе я создал функцию, вызывающую данные из firebase из каждого класса ... Например: получить всех игроков из X лиги { ДЛЯ каждого игрока в лиге { ПОЛУЧИТЕ информацию игроков ТОГДА ПОЛУЧИТЕ СЧЕТ ТОГДА дальше и дальше когда у нас есть вся информация APPEND к новому массиву } а затем ранжировать массив }

После всего этого я хочу перезагрузить табличное представление на VC

Так что мое решение работает при первоначальной загрузке, но если я вернусь назад и снова войду в экран, имена и изображения будут повторяться.

Точнее, когда индексы печатаются на консоли, я получаю "Игрок 1: Зак" "Игрок 2: Джон" Тем не менее, на экране неоднократно отображается изображение и имя Джона НО только этот класс ... Все остальные данные остаются там, где они должны быть. И оригинальные функции написаны одинаково.

Я думаю, что это связано с управлением памятью или я плохо написал свой обработчик завершения?

Вот код в новом классе массива:

Вы также заметите, что мое завершение () находится внутри цикла for in, который я НЕНАВИЖУ, но это единственный способ заставить функцию завершиться до завершения. В противном случае функция завершается до того, как данные будут готовы.

func getLeaderboard(leagueID: String, completion: @escaping ()->()) {

        print("League Count After removeAll \(self.rankedGolfers.count)")
        self.leagueMembers.getLeagueMembers(leagueID: leagueID) {
            print("HANDLER: Step 1: Get League Members")

            for member in self.leagueMembers.leagueMembers {

                print("Golfer Member ID: \(member.userID)")
                self.golferInfo.getGolferInfo(userKey: member.userID, completion: {
                    print("HANDLER: Step 2: Get player profile info")
                    print("Golfer Name3: \(self.golferInfo.golfers[0].firstName) \(self.golferInfo.golfers[0].lastName)")
                    self.handicapHelper.getRounds(userID: member.userID, completion: {
                        print("HANDLER: Step 3: Get players Handicap")
                        print("Golfer Handicap3: \(self.golferInfo.golfers[0].lastName): \(self.handicapHelper.handicap)")

                        self.leagueInfo.getLeagueInfo(leagueID: leagueID, completion: {
                            print("HANDLER: Step 4: Get league info")
                            let golferIndex = self.golferInfo.golfers[0]
                            let memberInfoIndex = self.leagueInfo.leagueInfo[0]
                            let golferID = member.userID
                            let profileImg = golferIndex.profileImage
                            let golferName = "\(golferIndex.firstName) \(golferIndex.lastName)"
                            let handicap = self.handicapHelper.handicap
                            let golferLeaguePardieScore = member.pardieScore
                            let leagueRoundsPlayed = member.numberOfRounds
                            let roundsRemaining = memberInfoIndex.leagueMinRounds - leagueRoundsPlayed
                            let currentWinnings = member.currentWinnings

                            let newGolfer = Leaderboard(golferID: golferID, profileImg: profileImg ?? "No Img", golferName: golferName, golferHandicap: handicap, golferLeaguePardieScore: golferLeaguePardieScore, roundsPlayedInLeague: leagueRoundsPlayed, roundsRemaining: roundsRemaining, currentWinnings: currentWinnings)

                            self.rankedGolfers.append(newGolfer)

                            print("HANDLER: Step 5: Add golfer to array")
                            //print("Golfer Name 4: \(newGolfer.golferName)")
                            //print("Rounds Remaining: \(newGolfer.roundsRemaining)")
                            print("league Member Count: \(self.rankedGolfers.count)")
                            self.getLeaderboardRanking()
                            print("HANDLER: Step 6: Rank Array")
                            //print("COMPLETION: \(self.rankedGolfers.count)")
                            completion()
                        })
                    })

                })
            }
        }

}

Спасибо за любую возможную помощь!

1 Ответ

0 голосов
/ 15 июня 2019

Я думаю, что мы можем решить эту проблему с помощью DispatchGroup, которая обеспечит загрузку всех данных для каждого пользователя, затем добавит пользователя в массив, используемый в качестве источника данных tableView, а затем перезагрузит tableView после завершения.

Для простоты мы начнем с класса UserInfo, в котором хранятся их uid, имя, любимая еда и гандикап.

class UserInfoClass {
    var uid = ""
    var name = ""
    var favFood = ""
    var handicap = 0
}

и массив класса var, используемый в качестве источника данных для tableView

var userInfoArray = [UserInfoClass]()

Тогда, предполагая, что у нас есть структура, подобная этой ...

users
   uid_0
      name: "Leroy"

handicaps
   uid_0
      amt: 4

fav_foods
   uid_0
      fav_food: "Pizza"

... вот функция, которая читает всех пользователей, затем перебирает каждого из них, заполняя UserInfoClass их именем и идентификатором пользователя, а также создает группу рассылки, которая также заполняет их любимую еду и гандикап. Когда это завершено, пользователь добавляется в массив dataSource, и когда все пользователи читаются, tableView перезагружается для отображения информации.

func loadUsersInfoAndHandicap() {
    let ref = self.ref.child("users")
    self.userInfoArray = []
    ref.observeSingleEvent(of: .value, with: { snapshot in
        let group = DispatchGroup()
        let allUsers = snapshot.children.allObjects as! [DataSnapshot]
        for user in allUsers {
            let uid = user.key
            let name = user.childSnapshot(forPath: "name").value as? String ?? "No Name"

            let aUser = UserInfoClass()
            aUser.uid = uid
            aUser.name = name

            group.enter()
            self.loadFavFood(withUid: uid) {favFood in
                aUser.favFood = favFood
                group.leave()
            }

            group.enter()
            self.loadHandicap(withUid: uid) { handicap in
                aUser.handicap = handicap
                group.leave()
            }

            group.notify(queue: .main) {
                self.userInfoArray.append(aUser)
            }
        }

        group.notify(queue: .main) {
            print("done, reload the tableview")
            for user in self.userInfoArray {
                print(user.uid, user.name, user.favFood, user.handicap)
            }
        }
    })
}

имя пользователя и uid читаются из основного узла пользователя, и вот две функции, которые читают их любимую еду и гандикап.

func loadFavFood(withUid: String, completion: @escaping(String) -> Void) {
    let thisUser = self.ref.child("userInfo").child(withUid)
    thisUser.observeSingleEvent(of: .value, with: { snapshot in
        let food = snapshot.childSnapshot(forPath: "fav_food").value as? String ?? "No Fav Food"
        completion(food)
    })
}

func loadHandicap(withUid: String, completion: @escaping(Int) -> Void) {
    let thisUser = self.ref.child("handicaps").child(withUid)
    thisUser.observeSingleEvent(of: .value, with: { snapshot in
        let handicap = snapshot.childSnapshot(forPath: "amt").value as? Int ?? 0
        completion(handicap)
    })
}

обратите внимание, что self.ref указывает на мою базу огня, поэтому замените ссылку на вашу базу огня.

Примечание. Я набрал это очень быстро, и, по существу, проверка ошибок не производится, поэтому, пожалуйста, добавьте это соответствующим образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...