Reputation:
In an app that I am developing, I need to show different view controllers based on whether the user has logged in or not when the app starts
HomeViewController
LoginViewController
Presently, I have coded in the following way-
the rootViewController
of window
of AppDelegate
is always LoginViewController
embedded inside a UINavigationController
.
In the viewDidAppear
method of LoginViewController
, I check if the user has logged in. If yes, then I push HomeViewController
.
In the HomeViewController
, when the user logs out, I pop the HomeViewController
to show LoginViewController
Is there a better way to do this?
Upvotes: 0
Views: 58
Reputation: 13577
Which is the better way is totally depends on your requirement and self-satisfaction.
Now think about your approach:
- If you're going with this approach then login screen will display for fraction of time. If it is okay for you then you can for it.
Now think about my approach:
- I think the better way is to check the same condition in
didFinishLaunchingWithOptions
instead ofloginVC
- If you are going this approach then your HomeVC is directly displayed after your splash screen. It is the main advantage of this approach
Code:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let isLoggedIn = true
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let navigationController = storyboard.instantiateViewController(withIdentifier: "NavigationController") as! UINavigationController
var viewController:UIViewController
if !isLoggedIn{
viewController = storyboard.instantiateViewController(withIdentifier: "LoginVC")
}else{
viewController = storyboard.instantiateViewController(withIdentifier: "HomeVC")
}
navigationController.viewControllers = [viewController]
window?.rootViewController = navigationController
return true
}
Just define the method in AppDelegate.swift
the file then calls it when required. Also, the same method is implemented in the sample code too.
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.logoutFromApp()
Code to change the root view controller:
func logoutFromApp(){
guard let rootNavigationController = window?.rootViewController as? UINavigationController else {
return
}
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "LoginVC")
rootNavigationController.viewControllers = [viewController]
}
Upvotes: 1
Reputation: 507
I think the better and easier approach will be to check is user signed in in AppDelegate (the best approach to create separate class for this logic).
You need to store user token in keychain and in AppDelegate check is user signed in. If it's require API request, while request is executing, replace Splash screen with spinner and depends from the API response, display necessary controller
Upvotes: 0
Reputation: 5076
Sometimes I use a custom root view controller, that can change a child view controller based on business logic (the root controller is a subclass of UIViewController not of UINavigationControler or UITabBarController). For example, the root controller can subscribe to notification about login/logout of user and show required view controller as a child view controller.
To support this, the root controller should be a custom container view controller (part with title Implementing a Container View Controller).
This solution allows to divide the interface to different story boards and save memory because you can destruct invisible view controllers.
Upvotes: 0