I have an AppState that can be observed:
class AppState: ObservableObject {
private init() {}
static let shared = AppState()
@Published fileprivate(set) var isLoggedIn = false
}
A View Model should decide which view to show based on the state (isLoggedIn
):
class HostViewModel: ObservableObject, Identifiable {
enum DisplayableContent {
case welcome
case navigationWrapper
}
@Published var containedView: DisplayableContent = AppState.shared.isLoggedIn ? .navigationWrapper : .welcome
}
In the end a HostView
observes the containedView
property and displays the correct view based on it.
My problem is that isLoggedIn
is not being observed with the code above and I can't seem to figure out a way to do it. I'm quite sure that there is a simple way, but after 4 hours of trial & error I hope the community here can help me out.
Working solution:
After two weeks of working with Combine I have now reworked my previous solution again (see edit history) and this is the best I could come up with now. It's still not exactly what I had in mind, because contained
is not subscriber and publisher at the same time, but I think the AnyCancellable
is always needed. If anyone knows a way to achieve my vision, please still let me know.
class HostViewModel: ObservableObject, Identifiable {
@Published var contained: DisplayableContent
init() {
self.contained = .welcome
setupPipelines()
}
private func setupPipelines() {
AppState.shared.$isLoggedIn
.map { $0 ? DisplayableContent.mainContent : .welcome }
.assign(to: &$contained)
}
}
extension HostViewModel {
enum DisplayableContent {
case welcome
case mainContent
}
}