Navigation Coordinator in SwiftUI

3.9k views Asked by At

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:

  1. App Launches
  2. App Coordinator Starts
  3. Loads "Start Scene"
  4. Start scene checks auth state and calls delegate on App Coordinator
  5. App Coordinator starts showHomeScene or showAuthScene

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.

0

There are 0 answers