I have an app that starts out in the login screen and when you log in it pushes a modal TabBarController. One of the tabs is settings which has a logout button, what would be the correct way to log out of my app and not have any issues such as memory leaks?
It really depends on how your users are logging in. What you probably need to do is the opposite of whatever you are doing to login. If all the login does is open the modal dialog, then closing it should be fine. It you are setting some kind of security token, then you will need to set it to nil.
Without knowing more about how your app works, there isn't much more I can say.
I know this is old, but if you want to present your login screen (because you logged out) as a modal, you can do this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
//Your login view controller, make sure you set the storyboard id
TTTLoginController *log = (TTTLoginController *)[storyboard instantiateViewControllerWithIdentifier:#"log"];
//wrap it in a navigation controller
UINavigationController *navBar=[[UINavigationController alloc]initWithRootViewController:log];
//present the modal view
[self.navigationController presentViewController:navBar animated:YES completion:nil];
Related
I am trying to add logic in the code to hide the login page if user is already logged in.
if (loggedin)
{
Push to MainViewController
}
else
{
Show LoginViewController
}
I know you can do this in AppDelegate, but I am hoping to add this logic in the LoginViewController.
Currently, my logic in the ViewController shows the login page for a second then push to the main page. Are there any ways to not see the login page completely?
i don't know if it exactly matches your needs but in one app i do the opposite:
i check in a viewController (the main page) if the user is logged and if it's not i show up the login page like this in the viewDidLoad method:
[self performSelector:#selector(showFirstTimeLogin) withObject:nil afterDelay:0.0];
I put it in the viewDidLoad so you don't see the "home view controller".
I hope it can help!
You Can check this in App Delegate
In application didFinishLaunchingWithOptions add this
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *viewController;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if([defaults objectForKey:#"email"]!=nil&&[defaults objectForKey:#"password"]!=nil)
{
viewController = [storyboard instantiateViewControllerWithIdentifier:#"RevealVC"];
}
else
{
viewController = [storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
}
self.window.rootViewController=viewController;
try to add this logic in viewdidload even before calling its super it may work but i can't make sure of that.
you can try a better trick by adding black view controller that you handle this logic at if he is logged in go to the main screen if not show the login screen and while checking that the use will have a black screen thinking the app is loading it will be there for second
and also having this logic is App delegate is not good behaviour from software design point of view
hope this answer will help good luck :)
Here is what I do...instead of starting the user on a login or logged in page, I start them on what I always name a "RouterViewController", I run through the logic needed to figure out where the user should be "routed" and use this librar: https://github.com/callumboddy/CBZSplashView to display a nice little animation so that to the user its actually a smooth process.
I have an app with 4 views, CheckAuthenticationView, HomeView, LoginView and DetailsView.
When the user starts the app the first view loaded is CheckAuthenticationView. This view checks the keychain for login information and if it exists, attempts to log the user in automatically and if successful, segues to DetailsView. If no information exists it performs a segue to the HomeView from which a user can then proceed to login.
Now on the DetailsView I have a button so the user can log out. If tapped, this clears any login information and performs an unwind (exit) segue to HomeView.
If a user does not logout but kills the app (restart phone etc), CheckAuthenticationView should produce a successful result meaning DetailsView will be loaded automatically. If this is the case, when I tap logout, the segue does not fire and the user remains on the DetailsView.
I am guessing that the segue does not happen because HomeView has not actually been created so there is nothing to segue to. Is there a way to segue to a view that has not yet been created?
Thanks
What do you mean by not yet created? If you haven't created the ViewController or any sort of view in your storyboard, then no you cannot segue to a view that does not exist. If you have created it then you can just call:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
UIViewController *homeView = [storyboard instantiateViewControllerWithIdentifier:#"HomeView"];
[self presentViewController:vc animated:YES(or NO) completion:nil];
I'm trying to see a different viewcontroller whenever my app gets a push notification. I tried to use
[self performSegueWithIdentifier:#"shootPicture" sender:self];
and
[self performSelectorOnMainThread:#selector(performSegueWithIdentifier:sender:) withObject:#"shootPicture" waitUntilDone:NO];
and
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *BombaViewController = [storyboard instantiateViewControllerWithIdentifier:#"BombaViewController"];
[self presentViewController:BombaViewController animated:NO completion:NULL];
All af the above example works, but they work JUST ONCE! After the viewcontroller goes back to the main tabbed controller, it doesn't work anymore.
I've also used NSLog to make sure that the system can actually intercept the push notifications.
Any suggestions?
I just put a button and dragged it to the starting Tabcontroller
This would indicate you have a new push / modal segue.
So, you aren't really going back, you're going to a new copy of your tab controller which is sitting in front of everything else. What you should really be doing is unwinding the segue that got you there, or connecting the button to an action in your code and calling dismissViewControllerAnimated:completion:.
I am doing something wrong, but not sure what it is. Bellow is the diagram of my storyboard.
/----(push)----login \
Start nav ctrl mainview nav ctrl
\----(modal) register /
When the user goes through login an event is received by appdelegate logindone, in login done I do:
self.window.rootViewController = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:#"MainView"];
This works just fine.
However if the user goes through register and completes registration with login the same loginDone is triggered but the code above results in blank view.
If I replace above code with
UIStoryboard* storyBoard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
MainCtrl *mainViewController = (MainCtrl*)[storyBoard instantiateViewControllerWithIdentifier: #"MainView"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:mainViewController];
self.window.rootViewController =navigationController;
This almost works, the view is displayed correctly, the only problem is that navigation bar is blank and it stays blank no matter where I go. Restarting app works of course because it bypasses register controller.
in register I do [self dismissViewControllerAnimated:NO completion:nil]; before calling loginDone, but this really makes no difference.
Any suggestions?
Edit:
self.window.rootViewController = [self.window.rootViewController.storyboard
instantiateViewControllerWithIdentifier:#"MainView"];
is the only thing that will work in normal flow i.e after login. Otherwise I get a crash "unavailable segue".
The way I fixed this is not exactly the way I wanted to fix it, but it works. I had to modify login done function that used to handle login finish work and transition to main view passing it parameter not to transition. On return I trigger a segue to main view from registration view. Still not sure why it was not working the way I had it done originally.
I would like to be able keep the text in a textfield persistent as I switch between view controllers.
I'm making a login screen and the login. However, if I go back to the login view controller after being in another view controller, the login information disappears (I'm pretty sure it's because it's a new instance of the view controller).
What I want to happen is that if a user enters in their login information and then goes back to the login view controller, they don't have to retype their info in.
Edit: Here is code for my programmatic segue to switch view controllers:
SecondViewController *secondViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"secondViewController"];
secondViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:secondViewController animated:YES completion:nil];
NSLog(#"Login SUCCESS");
Embed your first controller in a navigation bar. Next take out that code and use:
SecondViewController *secondViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"secondViewController"];
[self.navigationController pushViewController:secondViewController animated:YES];
If you want this to persist across launches of the program, then you should store the login information whenever they change it, and then read it back in whenever your login view controller loads and set the text field values from that.
You can store the information in a couple of different ways:
iOS Keychain
See this SO question for an example of how to store information securely in the keychain:
iOS: How to store username/password within an app?
NSUserDefaults
If you are only storing the username (and not the password) then you could use NSUserDefaults.
See this question for a good example:
Save string to the NSUserDefaults?
If the login controller is the first controller, the window's root view controller, it won't be deallocated unless you change which controller is the root. This doesn't happen when you're presenting and dismissing modal view controllers. I'm guessing that you're going from SecondViewController "back" to login controller by doing another modal presentation. Is that what you're doing? If so, that's wrong, that does create a new instance of login controller as you suspected. Instead, you should dismiss SecondViewController when you want to go back to the login controller. You need to do this in code rather than using a segue in the storyboard.