Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to conditionally switch root view controller at iOS app start-up

Tags:

ios

swift

login

New iOS developer here. I am working on a project which requires that the user log-in when they first open the app. From then on, I want the app to open directly to the main flow of the app (a tab bar controller in my case). After doing some research, I have come across what seems to be two main ways to do implement this functionality:

1) Conditionally set the root view controller of the app's window in the app delegate. For example:

    if userLoggedIn {
        let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
        let tabBarController: UITabBarController = storyboard.instantiateViewControllerWithIdentifier("TabBarController") as! UITabBarController
        self.window?.makeKeyAndVisible()
        self.window?.rootViewController = tabBarController
    } else {
        let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
        let logInViewController: LogInViewController = storyboard.instantiateViewControllerWithIdentifier("LogInViewController") as! LogInViewController
        self.window?.makeKeyAndVisible()
        self.window?.rootViewController = logInViewController
    }

2) Use a navigation controller as the app's root view controller, and conditionally set the view controllers managed by the navigation controller in the app delegate. For example:

    if userLoggedIn {
        let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
        let tabBarController: UITabBarController = storyboard.instantiateViewControllerWithIdentifier("TabBarController") as! UITabBarController

        let navigationController = self.window?.rootViewController as! UINavigationController
        navigationController.navigationBarHidden = true
        navigationController.setViewControllers([tabBarController], animated: true)
    } else {
        let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
        let tabBarController: ViewController = storyboard.instantiateViewControllerWithIdentifier("LoginViewController") as! ViewController

        let navigationController = self.window?.rootViewController as! UINavigationController
        navigationController.navigationBarHidden = true
        navigationController.setViewControllers([tabBarController], animated: true)
    }

If I go with the second option, I can easily transition to the app's main flow (let's say a tab bar controller) after I'm done logging in the user. In an appropriate place in the LogInViewController, I can say:

    // Transition to tab bar controller
    let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
    let tabBarController: UITabBarController = storyboard.instantiateViewControllerWithIdentifier("TabBarController") as! UITabBarController

    self.navigationController?.setViewControllers([tabBarController], animated: true)

Pretty easy.

As for the first method, I am not sure how I would transition to the main content of the app after logging the user in.

What I am looking for here is the "best" way to handle login flow. I've listed two methods but maybe there is another that is even better. Also, if the "best" method is the first I have listed, how can I get to my tab bar controller after I finish logging the user in? Thanks!

like image 263
kcstricks Avatar asked Jul 09 '15 02:07

kcstricks


1 Answers

Those are both fine options. One thing that I've done that has worked well is implemented a custom container view controller as the root of my app (this might be a subclass of my main view controller like a tab bar controller or navigation controller).

In this container view controller, I can put code to display and dismiss a login view controller based on the user's login status. Note: you can also use temporary full-screen views here to hide your app's main content while the login screen is shown/dismissed - this is an easy way to get very smooth app launch transitions.

I particularly like this method, because the rest of the app doesn't need to worry about the details. Your container can act like a normal tab bar controller or navigation controller, but underneath, you get to encapsulate all of the login UI logic in one place.

like image 110
Eric Avatar answered Oct 19 '22 04:10

Eric