Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Check for user in session in AppDelegate and trigger UIViewController if not

I have a Swift application, and what I'd like to do is that every time the app becomes active, I'd like to check for a user in session. If not found, I'd like to show a login view controller that I designed in my Storyboard. If found, I need everything to just resume as usual.

Where is the best way to trigger this check? Is AppDelegate's applicationDidBecomeActive the right place for this?

If yes, how do I actually instantiate the login view controller and show it? I have another home view controller, which is set to be my initial view controller. How do I manage this controller if and when I do end up successfully pushing the login view controller from the app delegate in case there is no user found in session? I don't want the home view controller to show up if a user is not found.

Any advise is greatly appreciated!

2 Answers

create a segue from your homeViewController to your loginVIewController. In your homeViewControllers viewWillAppear method, check to make sure the user is signed in. If they arent signed in, perform the segue to the login view controller.

Since this check occurs in viewWillAppear, if the user is not logged in the segue will happen before the home view appears on screen, so all you will see is the login view.

once a user logs in you can just dimiss the login view controller and you will be back on your home view.

depending on how your app is set up, you may have to do some hiding for your login view controller (hide tab bar/navbar etc)

Thanks Stone Preston ! Will this work for when the app becomes active from background with a different view controller in context?

I am doing this to deal with state restoration while also looking for user in session:

func application(application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -> Bool {
    return userInSession != nil
}

Am I missing anything here? Advise is much appreciated! Thanks!

Also, I'm not able to perform the segue. It complains:

2014-12-14 23:42:52.910 appname[78187:18685210] Warning: Attempt to present < appname.LoginUIViewController: 0x7fdcc1616970> on < appname.HomeUITabBarViewController: 0x7fdcc1746610> whose view is not in the window hierarchy!

I'm trying to perform it in viewWillAppear. A related post I found is here: http://stackoverflow.com/questions/15659526/how-to-fix-the-warning-view-is-not-in-the-window-hierarchy

If I transfer the code to viewDidAppear, I see the HomeUITabBarViewController before the LoginUIViewController shows up.

Any ideas?

Any ideas on this?

are you performing the segue from a tabBarController or a ViewController?

Tab bar view controller

thats probably the issue. you need to present from a child view controller of the tab bar, not the tab bar itself

Hmm..meaning that I'll need to segue from every tab's view controller? What will the single point of entry be in this case? My tab bar controller is set to be the initial view controller.

My tab bar controller is set to be the initial view controller.

yes, but the first thing the user actually sees is the view controller thats in the first tab correct. That would be the initial point of entry/exit

meaning that I'll need to segue from every tab's view controller?

no, if the user logs out from the initial tab, you only need a segue from that tab.

The way it should work is the app launches and the first tab will be getting ready to be displayed. before it shows you check to see if the user is logged in, if not perform the segue to the login view.

if they are logged in you dont do anything. When the user logs out from that initial tab you can perform the segue to the login view like before

if you want the user to be able to log out from anywhere in the app you might want to find a way to perform the segue from the tab bar controller, although im not sure how good of an idea that is, never really done it before

Hmm..okay that makes sense. So my first tab is a navigation controller leading up to a table view controller. I put the segue from the table view controller. But this time, although it doesn't throw error when using viewWillAppear, the view still appears before the login view controller is brought in. I'm using a modal segue.

Thoughts?

are you sure you implemented viewWillAppear and not viewDidAppear? if you are using a modal segue you may need to disable the animation in the attributes of the segue

Yep. This is what I got:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(true)

    if PFUser.currentUser() == nil {

        self.performSegueWithIdentifier("<...>", sender: self)
    }
}

Also, disabling animation still shows the table view controller before the login view controller appears on screen without animation.

pass the animated paramter to the super call, not true. see if that fixes it:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    if PFUser.currentUser() == nil {

        self.performSegueWithIdentifier("<...>", sender: self)
    }
}

Yeah that makes sense. The result is same though. Sometimes the login view controller appears quickly enough that the table view is not seen, but most times the table view controller is seen. Animation is disabled and behaves as expected.

try a push segue instead and see what happens

The table view controller still shows up before the login view controller. In addition, now the login view controller comes in from the right and the top bar and the bottom bar of the table view controller which is embedded into a navigation controller are visible.

top bar and the bottom bar of the table view controller which is embedded into a navigation controller are visible.

yes that is to be expected. you can hide them if you want.

im using pretty much the exact same setup as you and am not having the same issues as you. strange.

are you sure your segue is going from the child view to the login view? if you post your code to github or dropbox ill take a look at it more closely.

First of all, thank you so much for sticking with me on this!

I'll try to put stuff up somewhere and point out to it.

Just some other thoughts:

  1. is there a way to have the the child view controller initialize as hidden, and then make it visible if the segue doesn't have to be used? I tried changing this dynamically, and it sorta worked but the background is black instead of white. Ideas?

  2. can AppDelegate's applicationDidBecomeActive be used as the single point of entry check for user in session and then just create the login view controller if needed else resume as normal?

  1. not sure

  2. possible yes. you would ahve to obtain a reference to your view controller and perform the segue using that.

Yeah, I really like the segue approach. Okay, I'm going to research some more. Thanks a lot again!