Combine link UIViewController to @Published
I've set up a nice little view model with an @Published
state:
class ViewModel {
@Published private(set) var state = State.loading
private var cancellable: Set<AnyCancellable> = []
enum State {
case data([Users.UserData])
case failure(Error)
case loading
}
}
I've then linked to this in my UIViewController
's viewDidLoad
function:
private var cancellable: AnyCancellable?
override func viewDidLoad() {
super.viewDidLoad()
cancellable = viewModel.$state.sink{ [weak self] _ in
DispatchQueue.main.async {
self?.render()
}
}
}
however, when I link directly to the state it doesn't change when the state is changed from the view model (not shown in the code).
private func render() {
switch viewModel.state {
case .loading:
// Show loading spinner
print("loading render")
case .failure(let error):
// Show error view
print("failing render")
case .data(let userData):
// Show user's profile
self.applySnapshot(userData: userData)
print("loaded \(userData) render")
}
}
Now I can pass the state from my viewDidLoad, but how can I link directly to the viewModel state using Combine
and UIKit
?
Make sure your ViewModel conforms to ObservableObject
like so:
class ViewModel: ObservableObject
. This way it knows to react to changes, despite being a UIViewController
.