我正在为我的应用程序使用Firebase。我有2个标签。在第一个标签中,我从视图模型中获取数据,一切正常。在第二个视图中,我正在从相同的视图模型中获取。当我加载应用程序时,它将在第一个选项卡上启动。一切看起来都很好。当我切换到第二个选项卡时,一切看起来都很好。但是,当我切换回第一个选项卡然后再次切换至第二个选项卡时,数据获取仅在第二个选项卡中不起作用。请帮助!
[尝试调试时,我将打印语句放入视图模型的fetchData函数中。当我打开第一个选项卡时,它将调用一次函数。当我打开第二个选项卡时,它将调用两次。
这是我的视图模型
class ViewModel: ObservableObject {
@Published var routines = [Routine]()
func fetchData() {
print("ViewModel func")
Firestore.firestore().collection("routines").addSnapshotListener { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("No documents")
return
}
self.routines = documents.map { queryDocumentSnapshot -> Routine in
let data = queryDocumentSnapshot.data()
let uid = data["uid"] as? String ?? ""
let name = data["name"] as? String ?? ""
return Routine(id: .init(), uid: uid, name: name)
}
}
}
}
这里是指向两个不同选项卡的选项卡视图
TabView(selection: $selection) {
TodayView()
.tabItem {
Image(systemName: "sun.dust")
Text("Today")
}
.tag(1)
HomeView()
.tabItem {
Image(systemName: "arrow.2.circlepath")
Text("My Routines")
}
.tag(2)
}
在提供的代码中,我仅看到要解决的一件事-分配发布的属性应在主队列中
Firestore.firestore().collection("routines").addSnapshotListener { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("No documents")
return
}
let newValues = documents.map { queryDocumentSnapshot -> Routine in
let data = queryDocumentSnapshot.data()
let uid = data["uid"] as? String ?? ""
let name = data["name"] as? String ?? ""
return Routine(id: .init(), uid: uid, name: name)
}
DispatchQueue.main.async {
self.routines = newValues
}
}