🛣 Simple Navigation for iOS - ⚠️ Deprecated

What's New

Updates Support for Swift Package Manager

  • Updates Support for Swift Package Manager



Language: Swift Platform: iOS 8+ Carthage compatible Build Status License: MIT Release version

Reason - Get Started - Installation



Because classic App Navigation introduces tight coupling between ViewControllers. Complex Apps navigation can look like a gigantic spider web.

Besides the fact that Navigation responsibility is split among ViewControllers, modifying a ViewController can cascade recompiles and produce slow compile times.


By using a Navigation enum to navigate we decouple ViewControllers between them. Aka they don't know each other anymore. So modifying VCA won't trigger VCB to recompile anymore \o/

// navigationController?.pushViewController(AboutViewController(), animated: true)

Navigation code is now encapsulated in a AppNavigation object.


  • Decouples ViewControllers
  • Makes navigation Testable
  • Faster compile times

Get started

1 - Declare your Navigation enum

enum MyNavigation: Navigation {
    case about
    case profile(Person)

Swift enum can take params! Awesome for us because that's how we will pass data between ViewControllers :)

2 - Declare your App Navigation

struct MyAppNavigation: AppNavigation {

    func viewcontrollerForNavigation(navigation: Navigation) -> UIViewController {
        if let navigation = navigation as? MyNavigation {
            switch navigation {
            case .about:
                return AboutViewController()
            case .profile(let p):
                return ProfileViewController(person: p)
        return UIViewController()

    func navigate(_ navigation: Navigation, from: UIViewController, to: UIViewController) {
      from.navigationController?.pushViewController(to, animated: true)

A cool thing is that the swift compiler will produce an error if a navigation case is not handled ! Which would'nt be the case with string URLs by the way ;)

3 - Register your navigation on App Launch

In AppDelegate.swift, before everything :

Router.default.setupAppNavigation(appNavigation: MyAppNavigation())

4 - Replace navigations in your View Controllers

You can now call nagivations from you view controllers :


Bridge Navigation with your own enum type, here MyNavigation so that we don't have to type our own.

extension UIViewController {

    func navigate(_ navigation: MyNavigation) {
        navigate(navigation as Navigation)

You can now write :


Bonus - Tracking

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

Shave off compilation times

There is a nasty bug in Swift 3 compiler where the compiler rebuilds files even though they haven't changed. This is documented here :

Due to this bug, the compilation can go like this :

Change ViewController1 -> Build
-> Compiles ViewController1, referenced in MyAppNavigation so
MyAppNavigation gets recompiled. MyAppNavigation is referenced in AppDelegate which gets recompiled which references ... App -> ViewController2 -> ViewController3 -> ViewControllerX you get the point. Before you know it the entire App gets rebuilt :/

A good this is that most of the app coupling usually comes from navigation. which Router decouples.

We can stop this nonsense until this gets fixed in a future release of Xcode. Router can help us manage this issue by injecting our AppNavigation implementation at runtime.

In your AppDelegate.swift

// Inject  your AppNavigation  at runtime to avoid recompilation of AppDelegate :)
Router.default.setupAppNavigation(appNavigation: appNavigationFromString("YourAppName.MyAppNavigation"))

And make sure your AppNavigation implementation is now a class that is RuntimeInjectable

class MyAppNavigation: RuntimeInjectable, AppNavigation {



github "freshOS/Router"


Simply Copy and Paste Router.swift files in your Xcode Project :)

As A Framework

Grab this repository and build the Framework target on the example project. Then Link against this framework.


Like the project? Offer coffee or support us with a monthly donation and help us continue our activities :)


Become a sponsor and get your logo on our README on Github with a link to your site :)


  • Swift Tools 5.1.0
View More Packages from this Author


  • None
Last updated: Tue Feb 27 2024 15:57:48 GMT-1000 (Hawaii-Aleutian Standard Time)