Skip to content

freshOS/Router-deprecated

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Router

Router

![Language: Swift 3](https://img.shields.io/badge/language-swift 3-f48041.svg?style=flat) Platform: iOS 8+ Carthage compatible Build Status

[![License: MIT](http://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat)](https://github.com/freshOS/then/blob/master/LICENSE)

Release version

Decouples routing between ViewControllers

// From navigationController?.pushViewController(AboutViewController(), animated: true) // to navigate(.about)
  • Decouples Viewcontrollers
  • Testable navigation
  • 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.

Get started

1 - Declare your Navigation enum

enum MyNavigation: Navigation { case about }

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

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 :

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: MyNavigation) { navigate(navigation as Navigation) } }

You can now write :

navigate(.about)

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 GoogleAnalitcs.trackPage(navigation) }

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 : https://forums.developer.apple.com/thread/62737?tstart=0

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 {

Installation

Carthage

github "freshOS/Router" 

Manually

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.