5
votes

I've been attempting to implement a Login / Logout Flow for an iOS app in swift. Here's my storyboard -

Main Storyboard

In the main view controller (which is the blue screen), I have the following code implemented to detect that if the user is already signed in, then to automatically take them to the table view controller -

override func viewDidAppear(animated: Bool) {

    if PFUser.currentUser() != nil {

       self.performSegueWithIdentifier("test", sender: self)

    }

The issue is, that when i Sign In or Login through either one of the green screens, the Table View navigation bar appears different. The 'Sign Out' button appears properly when the user opens the app and is already logged in, however, logging in or signing in through the green screens, the navigation bar contains a '< Back' button.

Can someone explain how a login / logout flow needs to be implemented in storyboard and programatically in Swift. I've seen some Objective-C examples out there, but can't seem to find one in Swift. If anyone has a good example, it would be really helpful.

4
so, you are trying to remove the "back" button right? - Larry Pickles
in your viewdidload, well if you have one, you have to invoke the "hidesBackButton" property of the UIViewController, this is the way to make this disappear, if this isn't your question, then keep asking or respond to this comment. I would post a code example but there are too many moronic downvoters on the prowl now. - Larry Pickles
Thank you, this was one of the issues I was having with the Login flow. I added 'self.navigationItem.hidesBackButton = true' to viewDidLoad and it worked great! - SB2015
no problem, glad it worked out for you - Larry Pickles

4 Answers

10
votes

Swift 4 In LoginViewController's login button action

@IBAction func abtn_login(_ sender: Any) {

        let appDel:AppDelegate = UIApplication.shared.delegate as! AppDelegate
        let mainStoryBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)

        let centerVC = mainStoryBoard.instantiateViewController(withIdentifier: "InitialScreenTabBarController") as! InitialScreenTabBarController

        // setting the login status to true
        UserDefaults.standard.set(true, forKey: "isUserLoggedIn")
        UserDefaults.standard.synchronize()
        appDel.window!.rootViewController = centerVC
        appDel.window!.makeKeyAndVisible()


}

validate login according to your scenario.

In View Controller having the logout button.

@IBAction func abtn_logout(_ sender: Any) {

    UserDefaults.standard.set(false, forKey: "isUserLoggedIn")
    UserDefaults.standard.synchronize()

    let loginVC = self.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController

    let appDel:AppDelegate = UIApplication.shared.delegate as! AppDelegate

    appDel.window?.rootViewController = loginVC

}

In AppDelegate, didFinishLaunchingWithOptions

let userLoginStatus = UserDefaults.standard.bool(forKey: "isUserLoggedIn")

    if(userLoginStatus)
    {
        let mainStoryBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let centerVC = mainStoryBoard.instantiateViewController(withIdentifier: "InitialScreenTabBarController") as! InitialScreenTabBarController
        window!.rootViewController = centerVC
        window!.makeKeyAndVisible()
    }
6
votes

The < Back button is appearing because you are doing a push segue from the login view controllers to the tab bar controller. A better flow for the app would be to have the tab bar controller be your initial view controller. Then, in its viewDidAppear method, check that the user is logged in. If the user isn't logged in, segue modally WITHOUT animation to your login view controller. This will all happen without the user noticing and will allow the storyboard setup you want

2
votes

You're better off with a setup like the one here. The problem is that your login view resides in a navigation controller as well. Just bring it outside of that. The segue I've place in is a "Show"

Keep in mind that you can embed a Tab Bar controller in a view controller by going up to the menu bar: Editor -> Embed In -> Tab Bar Controller.

Then create a segue to the Tab Bar Controller and you're good to go.

enter image description here

But what if they're already logged in?

Then you want to save a Boolean flag to NSUserDefaults that knows if the user is logged in. Then recall that Bool in AppDelegate under the didFinishLaunchingWithOptions and applicationWillEnterForeground similar to this:

var isLoggedIn: Bool? // Get From user defaults

        let loginViewController = storyboard.instantiateViewControllerWithIdentifier("Login") as! UIViewController
        let homeViewController = storyboard.instantiateViewControllerWithIdentifier("HomeNav") as! UIViewController

        if isLoggedIn {
            self.window?.rootViewController = homeViewController
        }
        else {
            self.window?.rootViewController = loginViewController
        }
0
votes
  let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Register", bundle: nil)
        let initialViewController  = mainStoryboardIpad.instantiateViewController(withIdentifier: "navForLanding") as! UINavigationController
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.rootViewController = initialViewController
        self.window?.makeKeyAndVisible()