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
Deepak Ghosh
88 PointsCheck 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
Stone Preston
42,016 Pointscreate 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)
Deepak Ghosh
88 PointsAny ideas on this?
Stone Preston
42,016 Pointsare you performing the segue from a tabBarController or a ViewController?
Deepak Ghosh
88 PointsTab bar view controller
Stone Preston
42,016 Pointsthats probably the issue. you need to present from a child view controller of the tab bar, not the tab bar itself
Deepak Ghosh
88 PointsHmm..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.
Stone Preston
42,016 PointsMy 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
Deepak Ghosh
88 PointsHmm..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?
Stone Preston
42,016 Pointsare 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
Deepak Ghosh
88 PointsYep. 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.
Stone Preston
42,016 Pointspass 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)
}
}
Deepak Ghosh
88 PointsYeah 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.
Stone Preston
42,016 Pointstry a push segue instead and see what happens
Deepak Ghosh
88 PointsThe 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.
Stone Preston
42,016 Pointstop 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.
Deepak Ghosh
88 PointsFirst 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:
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?
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?
Stone Preston
42,016 Pointsnot sure
possible yes. you would ahve to obtain a reference to your view controller and perform the segue using that.
Deepak Ghosh
88 PointsYeah, I really like the segue approach. Okay, I'm going to research some more. Thanks a lot again!
Deepak Ghosh
88 PointsDeepak Ghosh
88 PointsThanks 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:
Am I missing anything here? Advise is much appreciated! Thanks!
Deepak Ghosh
88 PointsDeepak Ghosh
88 PointsAlso, 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?