如何 "forward" @Published 值
How to "forward" a @Published value
我对 SwiftUI 和 Combine 很陌生,尽管我对 Swift 有很多经验,对 ReactiveKit 也有一点经验,但我发现很难获得一些基本的东西。
例如,我试图在我的 ViewModel 上添加一个 isLoggedIn
属性,它应该只是 "forward" UserManager
class' isLoggedIn
属性。对于 ReactiveKit,这是相当微不足道的,但是对于 SwiftUI/Combine 我无法正常工作。该值仅设置一次,然后再也不会更新。
class UserManager: ObservableObject {
@Published private(set) var isLoggedIn = false
// This class has all the actual logic for logging in,
// keeping track of the logged in user and the auth status, etc.
}
class ViewModel: ObservableObject {
@Published var isLoggedIn = false
private let userManager: UserManager
init(userManager: UserManager) {
self.userManager = userManager
isLoggedIn = userManager.isLoggedIn // <- this doesn't work
userManager.$isLoggedIn.assign(to: \.isLoggedIn, on: self) // <- neither does this
}
func logout() {
userManager.logout()
}
}
struct ContentView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
// this will use viewModel.isLoggedIn at some point
}
}
以下应该有效。如果您不存储订阅者,它会自动取消。
private var subscribers = [AnyCancellable]()
init(userManager: UserManager) {
self.userManager = userManager
userManager.$isLoggedIn
.assign(to: \.isLoggedIn, on: self)
.store(in: &subscribers) // << subscriber must be kept
}
另一种方法是用手动 objectWillChange 替换 ViewModel 中的 @Published var isLoggedIn。
class ViewModel: ObservableObject {
var isLoggedIn: Bool {userManager.isLoggedIn}
private let userManager: UserManager
private var anyCancellable: AnyCancellable?
init(userManager: UserManager) {
self.userManager = userManager
anyCancellable = userManager.objectWillChange.sink {[weak self] _ in
self?.objectWillChange.send()
}
}
}
我对 SwiftUI 和 Combine 很陌生,尽管我对 Swift 有很多经验,对 ReactiveKit 也有一点经验,但我发现很难获得一些基本的东西。
例如,我试图在我的 ViewModel 上添加一个 isLoggedIn
属性,它应该只是 "forward" UserManager
class' isLoggedIn
属性。对于 ReactiveKit,这是相当微不足道的,但是对于 SwiftUI/Combine 我无法正常工作。该值仅设置一次,然后再也不会更新。
class UserManager: ObservableObject {
@Published private(set) var isLoggedIn = false
// This class has all the actual logic for logging in,
// keeping track of the logged in user and the auth status, etc.
}
class ViewModel: ObservableObject {
@Published var isLoggedIn = false
private let userManager: UserManager
init(userManager: UserManager) {
self.userManager = userManager
isLoggedIn = userManager.isLoggedIn // <- this doesn't work
userManager.$isLoggedIn.assign(to: \.isLoggedIn, on: self) // <- neither does this
}
func logout() {
userManager.logout()
}
}
struct ContentView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
// this will use viewModel.isLoggedIn at some point
}
}
以下应该有效。如果您不存储订阅者,它会自动取消。
private var subscribers = [AnyCancellable]()
init(userManager: UserManager) {
self.userManager = userManager
userManager.$isLoggedIn
.assign(to: \.isLoggedIn, on: self)
.store(in: &subscribers) // << subscriber must be kept
}
另一种方法是用手动 objectWillChange 替换 ViewModel 中的 @Published var isLoggedIn。
class ViewModel: ObservableObject {
var isLoggedIn: Bool {userManager.isLoggedIn}
private let userManager: UserManager
private var anyCancellable: AnyCancellable?
init(userManager: UserManager) {
self.userManager = userManager
anyCancellable = userManager.objectWillChange.sink {[weak self] _ in
self?.objectWillChange.send()
}
}
}