Bahn-X / swift-composable-navigator

An open source library for building deep-linkable SwiftUI applications with composition, testing and ergonomics in mind
MIT License
581 stars 25 forks source link

Add Providers #58

Open ohitsdaniel opened 3 years ago

ohitsdaniel commented 3 years ago

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

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) 
              }
          }
        ) 
     }
  }
}