【发布时间】:2021-10-30 10:27:12
【问题描述】:
我正在使用 SwiftUI,并且正在使用 MVVM,我的 VM 充当我的 EnvironmentObjects。
我首先创建一个 AuthSession 环境对象,其中存储了 currentUserId 的字符串。
然后,我为尝试包含 AuthSession 环境对象的 Offers 创建另一个环境对象,这样我就可以使用 Combine 过滤从数据库中提取的结果。当我将 @EnvironmentObject 属性添加到 Offer 视图模型时,我收到一条错误消息,指出未通过 AuthSession。这是有道理的,因为它不是视图。
我的问题是,最好在视图中对结果进行排序,还是有办法将 EnvironmentObject 添加到另一个 EnvironmentObject?我知道有一个答案here,但这个模型答案没有使用 VM 作为 EO。
应用文件
@main
struct The_ExchangeApp: App {
// @EnvironmentObjects
@StateObject private var authListener = AuthSession()
@StateObject private var offerHistoryViewModel = OfferHistoryViewModel(offerRepository: OfferRepository())
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(authListener)
.environmentObject(offerHistoryViewModel)
}
}
}
AuthSession.swift
class AuthSession: ObservableObject {
@Published var currentUser: User?
@Published var loggedIn = false
@Published var currentUserUid = ""
// Intitalizer
init() {
self.getCurrentUserUid()
}
}
OfferHistoryViewModel.swift - 在 startCombine() 中的 .filter 之后调用错误。
class OfferHistoryViewModel: ObservableObject {
// MARK: ++++++++++++++++++++++++++++++++++++++ Properties ++++++++++++++++++++++++++++++++++++++
// Access to AuthSession for filtering offer made by the current user.
@EnvironmentObject var authSession: AuthSession
// Properties
var offerRepository: OfferRepository
// Published Properties
@Published var offerRowViewModels = [OfferRowViewModel]()
// Combine Cancellable
private var cancellables = Set<AnyCancellable>()
// MARK: ++++++++++++++++++++++++++++++++++++++ Methods ++++++++++++++++++++++++++++++++++++++
// Intitalizer
init(offerRepository: OfferRepository) {
self.offerRepository = offerRepository
self.startCombine()
}
// Starting Combine - Filter results for offers created by the current user only.
func startCombine() {
offerRepository
.$offers
.receive(on: RunLoop.main)
.map { offers in
offers
.filter { offer in
(self.authSession.currentUserUid != "" ? offer.userId == self.authSession.currentUserUid : false) // ERROR IS CALLED HERE
}
.map { offer in
OfferRowViewModel(offer: offer)
}
}
.assign(to: \.offerRowViewModels, on: self)
.store(in: &cancellables)
}
}
错误
Thread 1: Fatal error: No ObservableObject of type AuthSession found. A View.environmentObject(_:) for AuthSession may be missing as an ancestor of this view.
【问题讨论】:
-
不可能
@EnvironmentObject并且大多数 SwiftUI 包装器仅适用于 SwiftUI 视图,这是@Published中的唯一包装器 -
我想通了。可以在那里使用 combine 对视图进行排序吗?这似乎与执行繁重工作的 VM 背道而驰。
-
你应该把工作放在视野之外。
标签: swiftui