我一直在关注Internet教程,该教程将Firebase数据放入SwiftUI的列表视图中,但是该教程使用了Firestore,所以我现在一个人呆着。我拥有所有数据,但是当我打开PlayerListView
时,列表为空。但是,当我打印时,所有数据都能完美打印。
这就是我所拥有的:
import SwiftUI
import Firebase
struct Player: Identifiable {
var id: String = UUID().uuidString
var username: String
var score: Int
}
struct PlayerListView: View {
@ObservedObject var viewModel = PlayerViewModel()
@Binding var showLeaderboard: Bool
var body: some View {
NavigationView {
List(viewModel.players) { player in
VStack(alignment: .leading) {
Text(player.username)
.font(.headline)
Text("\(player.score)")
.font(.subheadline)
}
}
.navigationBarTitle("Players")
.onAppear() {
self.viewModel.fetchData() { player in
print(player)
}
}
}
.onTapGesture {
self.showLeaderboard.toggle()
}
}
}
class PlayerViewModel: ObservableObject {
@Published var players = [Player]()
let ref = Database.database().reference().child("users")
func fetchData(completion: @escaping(Array<Player>) -> Void) {
ref.observeSingleEvent(of: .value, with: {(snapshot: DataSnapshot) in
if let result = snapshot.children.allObjects as? [DataSnapshot] {
for child in result {
let orderID = child.key
self
.ref
.child(orderID)
.queryOrdered(byChild: "score")
.observeSingleEvent(of: .value, with: {(snapshot: DataSnapshot) in
let value = snapshot.value as? NSDictionary
self.players.append(
Player(id: .init(),
username: value?["username"] as? String ?? "",
score: value?["score"] as? Int ?? 0))
completion(self.players)
})
}
}
})
}
}
答案 0 :(得分:0)
我稍微简化了您的代码(例如,无需实现完成处理程序),并修复了一些问题。
最大的问题是您没有将玩家ID映射到id
结构的Player
属性。由于List
要求其元素是可识别的,因此所有元素必须具有唯一的ID。但是,所有玩家都有相同的ID(一个空字符串),这导致List
视图中的条目重复。
这是更新的代码:
import SwiftUI
import Firebase
struct Player: Identifiable {
var id: String = UUID().uuidString
var username: String
var score: Int
}
struct PlayerListView: View {
@ObservedObject var viewModel = PlayerViewModel()
var body: some View {
NavigationView {
List(viewModel.players) { player in
VStack(alignment: .leading) {
Text(player.username)
.font(.headline)
Text("\(player.score)")
.font(.subheadline)
}
}
.navigationBarTitle("Players")
.onAppear() {
self.viewModel.fetchData()
}
}
}
}
import Foundation
import Firebase
class PlayerViewModel: ObservableObject {
@Published var players = [Player]()
let ref = Database.database().reference().child("users")
func fetchData() {
ref.observeSingleEvent(of: .value, with: {(snapshot: DataSnapshot) in
if let result = snapshot.children.allObjects as? [DataSnapshot] {
for child in result {
let orderID = child.key
self
.ref
.child(orderID)
.queryOrdered(byChild: "score")
.observeSingleEvent(of: .value, with: {(snapshot: DataSnapshot) in
let value = snapshot.value as? NSDictionary
self.players.append(
Player(id: value?["id"] as? String ?? UUID().uuidString,
username: value?["username"] as? String ?? "",
score: value?["score"] as? Int ?? 0))
})
}
}
})
}
}
这是我的测试数据的样子:
这是模拟器中UI的快照: