App Routing in iOS

One of the big enhancements in Swift is enums what are way more powerful than Objective-C enums. Allows more creative ways of structure information, and the one I want to explain is a method of structure app screen and app navigation

Even in a simple app, we need to handle segues or actions to push and pop between view controllers.

We probably have a similar structure all over the app. Two or three lines of repetitive code

let viewController = MyViewController() 
self.navigationController.pushViewController(viewController)
// or if we use storyboards
let storyboardViewController = self.storyboard?.instantiateViewControllerWithIdentifier("MyViewController") as? MyViewController
self.navigationController?.pushViewController(storyboardViewController!, animated: true)

How can improve it? I’ve been using what I called AppRouting for two projects and I can say it improves readability and extendibility of the app. That’s how it looks:

enum AppRouting{

case Landing,
Login,
EventList(user:UserProfile)

func getViewController()->UIViewController{
switch (self){
case .Landing:
return LandingController()
case .Login:
return SelectLoginController()
case .EventList(let user):
return EventListViewController(user:user)
}
// Search root view controller and if is a navigation controller pop last item
func pop(){

let appDelegate = AppDelegate.getInstance();
let rootvc = appDelegate.window?.rootViewController
if let navController = (rootvc as? UINavigationController){
navController.popViewControllerAnimated(true)
}

}
// Search root view controller and if is a navigation controller push current view controller
func push(){

let appDelegate = AppDelegate.getInstance();
let vc: UIViewController? = self.getViewController()
let rootvc = appDelegate.window?.rootViewController
if let navController = (rootvc as? UINavigationController){
navController.pushViewController(vc!, animated: true)
}

}

// Set selected view controller as unique view controller in a new navigation controller
func setAsRootController(){
let nav = UINavigationController()
nav.viewControllers = [self.getViewController()]
AppDelegate.getInstance().window?.rootViewController = nav
}

// Shows selected view controller as modal
 func showModal(){
AppDelegate.getInstance().window?.rootViewController?.presentViewController(self.getViewController(), animated: true, completion: nil)
}
// Hides selected view controller as modal
 func hideModal(){
AppDelegate.getInstance().window?.rootViewController?.dismissViewControllerAnimated(true, completion: nil)
}
}

With this aproach we have all the view controllers of the app in one place, if is a really large app we could split in several files, and push and pop is easy as:

func touchNextButton(){
     AppRouting.Login.push()
}

If our next view needs some parameters is as easy as:

AppRouting.EventList(user:newUser).setAsRootController()

If we use this aproach and with development progress we need to add a new parameter to a Route(View Controller) in AppRouting we get an error in all places where it needs to be modified.