Swift 类可观察对象@已发布变量始终为空
我正在尝试从firebase firestore获取收藏。下面是我的ViewModel,我无法将数据存储在@Published var categories对象中。我找不到确切的问题,我对斯威夫特有点陌生,但前一阵子同样的事情在起作用,我有什么做错了吗 FormViewModel.swiftSwift 类可观察对象@已发布变量始终为空,swift,firebase,google-cloud-firestore,swiftui,Swift,Firebase,Google Cloud Firestore,Swiftui,我正在尝试从firebase firestore获取收藏。下面是我的ViewModel,我无法将数据存储在@Published var categories对象中。我找不到确切的问题,我对斯威夫特有点陌生,但前一阵子同样的事情在起作用,我有什么做错了吗 FormViewModel.swift import Firebase import FirebaseFirestore class FormViewModel: ObservableObject { @Published var ca
import Firebase
import FirebaseFirestore
class FormViewModel: ObservableObject {
@Published var categories = [Category]()
private var db = Firestore.firestore()
func fetchCategories() {
db.collection("companies_by_category").addSnapshotListener { (QuerySnapshot, error) in
guard let documents = QuerySnapshot?.documents else {
print("No documents")
return
}
self.categories = documents.compactMap { (QueryDocumentSnapshot) -> Category? in
return try? QueryDocumentSnapshot.data(as: Category.self)
}
print(self.categories) // -> Able to get data
}
}
}
我的分类观点
struct CategoriesView: View {
@ObservedObject var viewmodel = FormViewModel()
var body: some View {
ScrollView {
List(self.viewmodel.categories) { category in
ZStack {
RoundedRectangle(cornerRadius: 15, style: .continuous)
//.foregroundColor(category.selected == true ? Color.yellow.opacity(0.5) : Color.white)
.foregroundColor(.white)
.shadow(color: Color.black.opacity(0.1), radius: 10, x: 0, y: 0)
VStack(spacing: 20) {
HStack {
Image("\(category.category)")
.foregroundColor(Color.gray)
.font(.system(size: 20.0))
Text(category.category)
.font(.system(size: 20.0, weight: .medium))
.foregroundColor(Color.black)
Spacer()
}
}
.padding()
}
}
}
.onAppear() {
self.viewmodel.fetchCategories()
}
}
}
您缺少一个事实,
addSnapshotListener
是一个异步函数。第二次打印不会返回任何数据,因为它是在addSnapshotListener
的异步网络请求返回任何数据之前同步执行的。您只能访问函数闭包内的addSnapshotListener
的异步数据
但是,实际视图未更新的原因与上述不同。您正在从异步闭包内部正确更新类别
数组,因此每当异步请求完成时,您的类别
将包含正确的数据
UI问题来自于您在视图中创建了
@ObservedObject
属性这一事实。这是完全错误的,因为每当视图
的@ObservedObject
属性更新时,视图将被重新绘制,这将导致其属性也被重新计算。可以通过在视图的init中注入viewmodel来修复此问题。查看有关如何将@ObservedObject
s注入视图
s的更详细说明。这是因为您正在对数据库进行异步调用,因此在返回数据之前执行打印。您不必担心这一点,因为categories
已发布,因此当数组获取值时,将通知任何观察者。谢谢,我忽略了它是异步的这一事实,但正如David在回答中解释的,问题不在于@published,但是使用@observed对象,因为我正在视图中创建它。嘿,谢谢你的回答,我的视图在主视图中初始化为-`MainView-@State var formViewModel=formViewModel()CategoriesView(viewModel:self.formViewModel)之后仍然没有显示`CategoriesView-`@ObserverdObject var viewmodel:FormViewModel`@RahulBajaj您试过调试代码吗?categories
是否实际更新并包含元素?如果在分类视图
的正文
中放置断点,则在更新分类
后是否会命中断点?