Я думаю, что мы можем решить эту проблему с помощью 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 указывает на мою базу огня, поэтому замените ссылку на вашу базу огня.
Примечание. Я набрал это очень быстро, и, по существу, проверка ошибок не производится, поэтому, пожалуйста, добавьте это соответствующим образом.