Historically using UIKit
we have always used the Coordinator Pattern to handle Navigation.
Starting a new app in SwiftUI
however it is not clear how to handle this.
For example, our currently flow would be:
- App Launches
- App Coordinator Starts
- Loads "Start Scene"
- Start scene checks auth state and calls delegate on App Coordinator
- App Coordinator starts
showHomeScene
orshowAuthScene
Something like
final class AppCoordinator: BaseCoordinator {
private(set) var navigationController: UINavigationController?
init(navigationController: UINavigationController?) {
self.navigationController = navigationController
}
override func start() {
showStartScene()
}
private func showStartScene() {
let configurator = StartConfigurator()
let viewController = configurator.create(self)
navigationController?.setViewControllers([viewController], animated: false)
}
private func showHomeScene() {
let coordinator = HomeCoordinator(self, navigationController: navigationController)
store(coordinator: coordinator)
coordinator.start()
}
private func showAuthScene() {
let coordinator = AuthCoordinator(self, navigationController: navigationController)
store(coordinator: coordinator)
coordinator.start()
}
}
extension AppCoordinator: StartSceneDelegate {
func userNeedsToAuthenticate() {
showAuthScene()
}
func userIsAuthenticated() {
showHomeScene()
}
}
However as we are not using UIViewController
how does navigationController?.setViewControllers([viewController], animated: false)
work?
Should we still just set using a UIHostingController
?
Something like -
navigationController?.setViewControllers([UIHostingController(rootView: StartView())], animated: false)
It seems a bit weird as I don't believe the SwiftUI views will really make use a UINavigationController
as they use NavigationView
and NavigationLink
.
Unless the UINavigationController
really just serves as a wrapper?
I was considering using@EnvironmentObject
within the coordinator and based on the auth state replacing the root view controller in the coordinator also.