Add providers for dependencies / ViewModels. Inspired by Flutter's providers, let's add a Provider view that initialises a dependency when needed and keeps its reference. Also inspired by TCA's WithViewStore, that moves all observable object observation out of the observing view and instead wraps the observation in WithViewStore, updating it's content whenever the store emits a change.
Problem description
Currently, ComposableNavigator is very TCA focused and assumes that people "hand-down" their view models into the NavigationTree. Flutter solves this by wrapping Widgets in ProviderWidgets that take care of initialising the Widget's dependencies and handing it down the WidgetTree through the context.
Considered solutions
Provider exposing the initialised dependency via the environment
-> Would need all dependencies to be ObservableObjects, potentially crashing the app when an EnvironmentObject is not initialised.
Explicitly passing the dependency into a build content closure ✅
struct DetailScreen: Screen {
let presentationStyle: ScreenPresentationStyle = .push
struct Builder<ViewModel: DetailViewModel & ObservableObject>: NavigationTree {
let viewModel: () -> ViewModel
var builder: some PathBuilder {
Screen(
DetailScreen.self,
content: {
Provider(
observing: viewModel,
content: { viewModel in
// DetailView.init(viewModel: DetailViewModel), no ObservableObject needed here.
DetailView(viewModel: viewModel)
}
}
)
}
}
}
Idea
Add providers for dependencies / ViewModels. Inspired by Flutter's providers, let's add a Provider view that initialises a dependency when needed and keeps its reference. Also inspired by TCA's WithViewStore, that moves all observable object observation out of the observing view and instead wraps the observation in WithViewStore, updating it's content whenever the store emits a change.
Problem description
Currently, ComposableNavigator is very TCA focused and assumes that people "hand-down" their view models into the NavigationTree. Flutter solves this by wrapping Widgets in ProviderWidgets that take care of initialising the Widget's dependencies and handing it down the WidgetTree through the context.
Considered solutions