Issue #694
I usually structure my app to have 1 main ObservableObject
called Store
with multiple properties in it.
final class Store: ObservableObject {
@Published var pricingPlan: PricingPlan()
@Published var preferences: Preferences()
}
struct Preferences {
var opensAtLogin: Bool = true
}
final class PricingPlan: ObservableObject {
@Published var isPro: Bool = true
}
SwiftUI for now does not work with nested ObservableObject
, so if I pass Store
to PricingView, changes in PricingPlan
does not trigger view update in PricingView.
struct MainView: View {
@ObservedObject
var store: Store
var body: some View {
VStack { geo in
}
.sheet(isPresented: $showsPricing) {
PricingView(
isPresented: $showsPricing,
store: store
)
}
}
}
There are some workarounds
Pass nested ObservableObject
So that View observes both parent and nested objects.
PricingView(
store: store,
pricingPlan: store.pricingPlan
)
Use struct
This forces us to deal with immutability also, as with reference type PricingPlan, someone could just save a reference to it and alter it at some point.
struct PricingPlan {}
Listen to nested objects changes
Every ObservableObject
has a synthesized property objectWillChange
that triggers when any @Publisshed
property changes
final class Store: ObservableObject {
@Published var pricingPlan = PricingPlan()
private var anyCancellable: AnyCancellable? = nil
init() {
anyCancellable = pricingPlan.objectWillChange.sink { [weak self] _ in
self?.objectWillChange.send()
}
}