【发布时间】:2021-05-15 12:31:01
【问题描述】:
我正在努力将 Firestore 存储库整合到 SwiftUI 2 应用程序中。列表视图会适当加载,并在 Firestore 集合中的数据发生更改时自动刷新。 NavigationLink 正确加载适当的 DetailView。 DetailView 上的一个按钮设置为更改相关文档内的数据,并且可以正常工作,但是 DetailView 页面没有刷新正确的数据(退出到列表视图并返回时正确显示);同样,DetailView 不会响应对其他地方的集合所做的更改。
我尝试使用 ObservedObject 和 State 的各种配置,但无法获得预期的结果。
任何帮助将不胜感激。下面列出的 Snipped Code 显示了流程,并以状态字段为例。
客户存储库
class CustomerRepository: ObservableObject {
private let path: String = "customers"
private let store = Firestore.firestore()
@Published var customers: [Customer] = []
private var cancellables: Set<AnyCancellable> = []
init() {
store.collection(path)
.addSnapshotListener { querySnapshot, error in
if let error = error {
print("Error getting customers \(error.localizedDescription)")
return
}
self.customers = querySnapshot?.documents.compactMap { document in
try? document.data(as: Customer.self)
} ?? []
}
}
func update(_ customer: Customer) {
guard let customerID = customer.id else { return }
do {
try store.collection(path).document(customerID).setData(from: customer)
} catch {
fatalError("Unable to update record: \(error.localizedDescription)")
}
}
}
客户列表视图模型
class CustomerListViewModel: ObservableObject {
@Published var customerViewModels: [CustomerViewModel] = []
private var cancellables: Set<AnyCancellable> = []
@Published var customerRepository = CustomerRepository()
init() {
customerRepository.$customers.map { customers in
customers.map(CustomerViewModel.init)
}
.assign(to: \.customerViewModels, on: self)
.store(in: &cancellables)
}
}
客户视图模型
class CustomerViewModel: ObservableObject, Identifiable {
private let customerRepository = CustomerRepository()
@Published var customer: Customer
private var cancellables: Set<AnyCancellable> = []
var id = ""
init(customer: Customer) {
self.customer = customer
$customer
.compactMap { $0.id }
.assign(to: \.id, on: self)
.store(in: &cancellables)
}
func update(customer: Customer) {
customerRepository.update(customer)
}
}
客户列表视图
struct CustomerListView: View {
@ObservedObject var customerListViewModel = CustomerListViewModel()
var body: some View {
NavigationView {
List {
ForEach(customerListViewModel.customerViewModels) { customerViewModel in
NavigationLink(
destination: CustomerDetailView(customerViewModel: customerViewModel)) {
CustomerCell(customerViewModel: customerViewModel)
}
}
}
}
}
}
客户详情视图
struct CustomerDetailView: View {
var customerViewModel: CustomerViewModel
var body: some View {
VStack {
Text(customerViewModel.customer.status.description)
}.onTapGesture {
nextTask()
}
}
private func nextTask() {
switch customerViewModel.customer.status {
case .dispatched:
customerViewModel.customer.status = .accepted
...
default:
return
}
update(customer: customerViewModel.customer)
}
func update(customer: Customer) {
customerViewModel.update(customer: customer)
}
}
【问题讨论】:
-
我在这里有类似的问题stackoverflow.com/questions/66141387/…
-
谢谢。我查看了您收到的两个建议,但似乎都没有解决我的问题。但如果我得到解决方案,我会将您的问题添加为书签。
标签: firebase google-cloud-firestore swiftui