iosauthenticationuistoryboardlogout

Best practices for Storyboard login screen, handling clearing of data upon logout


I'm building an iOS app using a Storyboard. The root view controller is a Tab Bar Controller. I'm creating the login/logout process, and it's mostly working fine, but I've got a few issues. I need to know the BEST way to set all this up.

I want to accomplish the following:

  1. Show a login screen the first time the app is launched. When they login, go to the first tab of the Tab Bar Controller.
  2. Any time they launch the app after that, check if they are logged in, and skip straight to the first tab of the root Tab Bar Controller.
  3. When they manually click a logout button, show the login screen, and clear all the data from the view controllers.

What I've done so far is set the root view controller to the Tab Bar Controller, and created a custom segue to my Login view controller. Inside my Tab Bar Controller class, I check whether they are logged in inside the viewDidAppear method, and a perform the segue: [self performSegueWithIdentifier:@"pushLogin" sender:self];

I also setup a notification for when the logout action needs to be performed: [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(logoutAccount) name:@"logoutAccount" object:nil];

Upon logout, I clear the credentials from the Keychain, run [self setSelectedIndex:0] and perform the segue to show the login view controller again.

This all works fine, but I'm wondering: should this logic be in the AppDelegate? I also have two issues:

I'm open to reworking this. I've considered making the login screen the root view controller, or creating a navigation controller in the AppDelegate to handle everything... I'm just not sure what the best method is at this point.


Solution

  • Here is what I ended up doing to accomplish everything. The only thing you need to consider in addition to this is (a) the login process and (b) where you are storing your app data (in this case, I used a singleton).

    Storyboard showing login view controller and main tab controller

    As you can see, the root view controller is my Main Tab Controller. I did this because after the user has logged in, I want the app to launch directly to the first tab. (This avoids any "flicker" where the login view shows temporarily.)

    AppDelegate.m

    In this file, I check whether the user is already logged in. If not, I push the login view controller. I also handle the logout process, where I clear data and show the login view.

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    
        // Show login view if not logged in already
        if(![AppData isLoggedIn]) {
            [self showLoginScreen:NO];
        }
    
        return YES;
    }
    
    -(void) showLoginScreen:(BOOL)animated
    {
    
        // Get login screen from storyboard and present it
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
        LoginViewController *viewController = (LoginViewController *)[storyboard instantiateViewControllerWithIdentifier:@"loginScreen"];
        [self.window makeKeyAndVisible];
        [self.window.rootViewController presentViewController:viewController
                                                 animated:animated
                                               completion:nil];
    }
    
    -(void) logout
    {
        // Remove data from singleton (where all my app data is stored)
        [AppData clearData];
    
       // Reset view controller (this will quickly clear all the views)
       UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
       MainTabControllerViewController *viewController = (MainTabControllerViewController *)[storyboard instantiateViewControllerWithIdentifier:@"mainView"];
       [self.window setRootViewController:viewController];
    
       // Show login screen
       [self showLoginScreen:NO];
    
    }
    

    LoginViewController.m

    Here, if the login is successful, I simply dismiss the view and send a notification.

    -(void) loginWasSuccessful
    {
    
         // Send notification
         [[NSNotificationCenter defaultCenter] postNotificationName:@"loginSuccessful" object:self];
    
         // Dismiss login screen
         [self dismissViewControllerAnimated:YES completion:nil];
    
    }