Decouples routing between ViewControllers
// From navigationController?.pushViewController(AboutViewController(), animated: true) // to navigate(.about)[x] Decouples Viewcontrollers
[x] Testable navigation
[x] Faster compile times
A cool side effect of extracting navigation logic on big projects is improving compilation times. Indeed Strong dependencies due to navigation code often makes Xcode recompile files you never modified. Router enables you to extract your routing logic in a separate file.
enum MyNavigation: Navigation { case about }struct MyAppNavigation: AppNavigation { func viewcontrollerForNavigation(navigation: Navigation) -> UIViewController { if let navigation = navigation as? YPNavigation { switch navigation { case .about: return AboutViewController() } } return UIViewController() } func navigate(_ navigation: Navigation, from: UIViewController, to: UIViewController) { if let myNavigation = navigation as? MyNavigation { switch myNavigation { case .about: from.navigationController?.pushViewController(to, animated: true) } } } }In AppDelegate.swift, before everything :
Router.default.setupAppNavigation(appNavigation: MyAppNavigation())You can now call nagivations from you view controllers :
navigate(MyNavigation.about)Bridge Navigation with your own enum type, here MyNavigation so that we don't have to type our own.
extension UIViewController { func navigate(_ navigation: YPNavigation) { navigate(navigation as Navigation) } }You can now write :
navigate(.about)Another cool thing about decoupling navigation is that you can now extract traking code from view Controllers as well. You can be notified by the router whenever a navigation happened.
Router.default.didNavigate { navigation in // Plug Analytics for instance GoogleAnalitcs.trackPage(navigation) }