I'm writing an iOS application that includes a UITabBarController, where one of the tabs is the user's profile. However, if the user is not signed in, I would like the application to display a different ViewController (Sign in/Sign up) instead.
I currently have the profile tab routing to a navigaion controller which has its RootViewController as ProfileViewController. In ProfileViewController's viewDidLoad, I have a check to see if the user is signed in. If the user is not, It performs a segue to SignInSignUpViewController which eventually loops back to ProfileViewController.
This approach is over-complicated and broken in a couple ways. For example, the navigation controller allows for the user to back into the signup/signin view controller after they've already signed in.
I feel like this is a pretty common idiom in iOS, but I can't find a good solution online. Anyone have any ideas?
Thanks in advance!
You might want to take a look at the UINavigationController method – setViewControllers:animated:. After you've logged in call this and pass your profile ProfileViewController. It will then be at the top of the stack, so the user won't be able to navigate back to the login view controller.
Related
I am new to iOS ran into a problem, I have successfully implemented SWRevealViewController side menu and it works if I put the view controller as initial screen but when it comes to showing it after login procedure it does not show up the menu, so after searching the web for quite some time I found out that I need to design a separate story board for login and register and separate for other screens.. so I did it as per that. Still, I have problems in showing up my side menu. My code does not get in
if revealViewController() != nil{ }
It returns NULL so the code does not go ahead.
And this is my second storyboard:
I am using UserDefaults to keep whether the user is logged in or not and storing user profile details in UserDefaults as well to be used within the app for future.
No need to use second storyboard.
You can simply switch between UIViewControllers by implementing a container view controller, if not using segues for specific reasons.
However, what I would suggest is to set your main view controller, revealViewController?, as an initial view controller, and check login status (using your UserDefaults) on viewDidLoad(). If there's no available login info, modally present another view controller for the login process. Then simply dismiss the login view controller if login succeeded.
I am trying to figure out the best UX for handling 'protected' view controllers throughout an iOS app, that require authentication. For example, say certain view controllers require authentication in my app. If a user navigates to that view controller I can have a check in viewWillAppear that checks if a user is authenticated and show the login screen if they are not. But here is the tricky part... What happens if they cancel the login? A whole set of issues can arise. I can pop the view controller they are on, but what if the previous controller they came from also requires authentication. I can potentially end up with a chain of popping view controller and showing a login view... This seems like an awful user experience.
I can think of one solution which is working now but doesn't seem correct:
An unauthenticated user enters a 'protected' view controller
Replace the AppDelegate's window.rootViewController with the login screen
When the user logs in successfully they are brought to the first screen of the app (losing the state of where they were in the app).
I assume that this is a common problem that other devs have faced. I couldn't find any best practices for handling this and figured you guys would be able to recommend some tips?
Add a flag in Login view controller that you are coming to the protected view controller from Login View and set that flag to YES when user clicks cancel button on login screen and use popToRootViewController to pop to root view controller. and in rootViewController's viewWillAppear, set flag to NO.
User doesn't need the other protected view controllers if they select cancel in login.
and as per my observation, user doesn't have a chance to go to multiple protected view controllers at once, because, if user comes to first protected view controller, you are showing him login screen and if he cancels it, you are pop ing the view. So there is no chance for user though. either way, the above method works for you.
my situation is:
My app need to display the views normally but when I press and call a view that will display some sensitive information, I need to be logged, so a login view need be displayed. The trick for me is: when I call presentViewController and load the view, the view is called in a modal way that hide the tab bar and I can`t access other views.
Other thing is I`m doing the check on if user is logged in viewDidAppear, is that a bad practice?
tks for any reply.
In such cases, the concept of container view controller is your friend. You have a UIViewController that encapsulates all the business logic, in your case, the login logic. It manages a view that, say, has a form-like structure where the user enters the data. You can add this as a child of the parent view controller (where your tabs exist). After he presses login (or something), you can remove this child view controller and continue where you left off!
No, checking in viewDidAppear for session validation is something that I do all the time, I think you are fine here.
Edit
In response to a comment. Yes, session validation viewDidAppear can cause problems. A careful application design is the key here. I personally store the login information of the user (as a user model) in NSUserDefaults and remove it whenever the user logs out.
I am making a new application there i have 5 tabs in it, its a user based application so i have to get the credentials of users login and passwords .
I am using storyboards with Arc , since its a Tabbed application so my initial view controller is my tab view controller , I wish to add a login screen also (probably as Modal View or an).
I am not able to think the perfect way to add a login screen in the tabbed application .
Should i call it from app delegate or in view will appear or some of these methods . I tried some of the code but ended up with warning like unbalanced call etc.
Need your valuable suggestions :)
Thanks in advance !!!
Just two options (of course there are more):
Use one UIViewController as rootViewController in the beginning of your App. Once the login is successful it will switch the window's rootViewController.
Put the UITabBarController as rootViewController, on viewWillAppear, check if the login has been made, if not, just show the Login's UIViewController
I've been struggling with this a long time now, so I finally gave up on trying to find the answer and decided to ask it right away.
On my app I have a user log in page. The app has a TabBarViewController that has some NavigationControllers in it's items.
My last effort was to put the login screen embedded on a NavigationBarController and make it the Initial View Controller, as in the picture below.
When the app is launched, if the user is logged in the LogInViewController 'segues' to the TabBarController and everything is fine. When the user logs out in the ProfileViewController, there's a segue in this ViewController 'segueing' to the initial view controller.
In the other hand, if no user is logged in, the LogInViewController presents a view so that the user can insert username and password. If credentials are correct the LogInViewController 'segues' to the TabBarController. The problem is that at this point, even if the app is still working good, i get the following warning:
Warning: Attempt to present TabBarViewController: 0xa19a670 on UINavigationController: 0xa526370 while a presentation is in progress!
So I assume this is not the best way to handle all this LogIn/LogOut process.
My question is, where should I put the LogInScreen in the hierarchy?
If by any chance my layout/hierarchy is correct, how to make the warning go away?
You should make your Home screen as your rootViewController and in once your application starts or become active, you can check if user is logged in or not, if not then present the LoginScreen Modally, it will avoid the mess with other NavigationController or TabBarController
Alternate could be to put all the ViewControllers in a MutbaleArray and set the current Index of TabBarController according to the view you want to show? if you don't want to show the LoginScreen after user Logged in, just remove it from your MutableArray, check my answer here, it might help your cause