I have a Login interface, user interface, and a Main menu.
When I'm logging in, I switch on my user interface.
if I do a UIModalTransition, and if I come back to the page, I need to RE-login again, it's a problem for me.
I search a method for Switch between view but don't close them, because if you closed them, views restart, it's the same for UIWebview, I would like to switch between views without closed and reset views.
Is it possible ?
I don't really know what kind of Code is it.
If you have ideas, please tell me.
In this answer i tried to explain the view controllers orchestration as i see it.
The idea is to create the manager class taking care of elements storage and presentation. It also mentions the way to manage the login information.
You can use pushViewController ie..
[self.navigationController pushViewController:yourUserInterFaceViewController animated:YES]; for transition between login and user interface.
you can use 3 ways
1)pushing the view into UINavigationController
2)presenting the view with ModalViewController
3)adding subView to rootViewController and remove it using removeFromSuperView when needed.
(you can allocate them when app launches and access them using
[YourAppDelegate sharedApplication].yourViewController)
Since your appDelegate is a singleTon class it will always return the same viewcontroller you've allocated at the time of launching the app. You can use Lazy Load also.
May be this will help.
Related
I have been searching the net, and i have found many very good examples on how to create a login page for your iPhone app. However... none of then meets my demands, an since i am new to iPhone development( i know java / c / C++ and objective-c), so the programming itself is not the issue.. The issue is where to put the code and what design patterns to use..
My app is a basic tabbar controller with 3 tabs that could contain navigation controllers, but that is not important.. it is the part before the tabbar controller i am interrested in, namely the need to authenticate the user towards a Lotus Domino Server. I have the authenification code working, so that is not the issue either..
By the way, i am concentrating on IOS5 and using storyboards..
Where do i put the "check if user is still authenticated" code ? The domino server will log the user out after 1 hour, so if the user has the app open(in background) then the code that downloads data will die if the user is not told that the session has expired..
So here is what i would like..
When the app launches, show the login page. This is working for now with the Login View Controller as initial controller, and a modal segue to the tabbar controller..
Next time the App is launched(either from background or from new is user has closed it completely), check if username and password is stored in userdefaults, and then just login in background, and if that fails(password has changed or another failure) then show the login view controller again..
So to sum up, where do i put the "part 2" code ? I have a seperate authenticator class that is using delegates, and i can use this class to perform the authentification, and the it will answer back if all is good.
Do i put this in the AppDelegate code ? If i put it in one of the tabbar viewcontrollers, then there might be an issue with the user having tab2 open when launching after 2 hours, and if the check is in tab1, then tab 2 will fail.. Should i put the code in ALL the tabbar viewcontrollers ? Naaa, that is ugly..
I am leaning towards the AppDelegate(appdidbecomeactive), but can that be used as delegate in my authenticator class ?
That was a bit long, sorry for that, but i needed to explain my problem fully so people would understand what i need..
Thank you for your help.. This is my first post, but this forum is fantastic :)
I'd definitely put both part one and part two code in the AppDelegate.
This allows you to create the appropriate viewcontroller at app start and remove the tabbarcontroller from within the AppDelegate if the authentication times out etc.
I'm not sure about your modal segue to a tabbarcontroller though (I'm not familiar with storyboards yet though). Modal implies you wouldn't be able to present any other view modally on top of the tabbar controller. I think it sounds like it would be much more appropriate to create your logincontroller and tabbarcontroller programmatically and add/remove them directly in your application’s main window as needed from your AppDelegate.
I would tell the AppDelegate to check the login status very time the tab is changed or data loaded.
In my app there is authentication required, so when you launch one of the tabs on tab bar, "class A" checks are there credentials saved if not, "class B" modal view controller with fields to login launches.
So my question is : in which method in class A (loadView, viewWillAppear or maybe in another one) should be implemented checking if there are credentials saved and other stuff described above.
And my additional second question is:
is pushing modalviewcontroller correct way to show login screen, or i should do that differently?
Thank you for reply guys.
OH ! One More Thinh
And one more thing. I've done implementing LoginView by adding delegate and presenting ModalVC (Harkonian the Piquant's method). But in my tab bar app i have got very confusing problem. I mean when user taps login button (assume that everything was correct and he's able to secured data) how PROPERLY switch to tab where is secured info. I mean previously selected tab.
i did it by adding in
-(IBAction) login {
//some code
self.tabBarController.selectedIndex =1;
And it seem to work good but is it correct ?
I have a very similar use case in my app -- it requires a passcode to authenticate. After a lot of testing and tweaking I found the following design to be the best approach:
Don't use class A to launch your credentials VC -- use the app delegate instead.
For security purposes, typically you'll want the credentials VC to show before the user can view the underlying view. It's much easier to handle this in the app delegate than in a VC. In addition, you need to consider what happens when your app is backgrounded -- a screen shot is taken of the current state of the app. If you are using viewController A to show the credentials view, when the app relaunches the user will be able to see whatever sensitive information was visible on app close until the app finishes launching and VC A presents the credentials VC.
Don't insert your credentials view into an existing ViewController -- use a new UIWindow instead.
You don't ever want any other view to be able to sit on top of your credentials view. Ever. Even views that would normally always be on top, like UIAlertView. The easiest way to achieve this is to have a special UIWindow just for your credentials view. Show this window and hide the primary app window whenever you need to display the credentials view.
How does this approach look in practice?
If you are at all interested in how well this design works, you can check out the passcode feature in Audiotorium Notes for iPad. I spent a lot of time with this design to make sure it was as secure as possible.
If you have any specific implementation quests feel free to ask and I'll try to answer them.
I'm new to iOS development, obviously, and I'm running into a bit of an issue with many of the tutorials that I find online. While I understand the majority of the code that is going into these programs, I cannot figure out how to translate this one fact, which is probably simple.
Many tutorials either use the Navigation-based template or View-based template, but I would like to try building tab bar applications. Tutorials either use the App Delegate or rootViewController (being the navigation controller), but since my tab bar is my rootViewController, I always run into an issue. I'm also unable to use the applicationDidFinishLaunching method in most of my code, because it technically only applies to the first tab at launch.
These are my questions:
Is there a way to "translate" these files into new classes (for example, creating an instance of NSObject for the App Delegate code for each individual tab or creating instances of UINavigationViewController)?
If I can create the instance of NSObject, how do I ensure that the code links up to the objects that I create in my viewController?
If I can create a file that uses UINavigationController, how do I trick the program into temporarily allowing the Nav Controller to be the rootViewController.
Many thanks in advance!
Right off the top of my head, I can only answer number 3 for you, you could do that in one of two ways that I am aware, and if anyone sees either of these is incorrect or bad practice, I hope someone corrects me, as this is what I have been doing.
[appDelegate.window addSubview:appDelegate.newRootViewController.view];
appDelegate.window.rootViewController = appDelegate.newRootViewController;
or
[self.navigationController pushViewController:appDelegate.newRootViewController animated:YES];
Both should accomplish the same thing, though if you can help it, the second version is ideal. Its also worth noting that for the first one, there is no tricking, you are actually setting the rootViewController of your app to something different.
I'll do some digging and see if I can answer any of your other questions for you too.
Edit: So after re-reading and thinking a bit more about it, I think the other two questions can be answered by maybe clarifying a tab bar application. Unfortunately, I'm fairly new to iOS as well, and I haven't had to opportunity to create a tab bar application, so I don't want to give you incorrect info. I would recommend checking out http://www.techotopia.com/index.php/Creating_an_iOS_4_iPhone_Multiview_Application_using_the_Tab_Bar_%28Xcode_4%29 and hopefully it can give you a little bit of a better idea of how Tab Bar Apps work. I've been using that eBook along with another from that site combined with Ray Wenderlich's tutorials to teach myself.
Anyways, I hope this helps to some extent, if you want me to try to clarify or go into detail on anything just comment and I'll see if I can help.
Good Luck!
-Karoly
You're misunderstanding how the app delegate works.
It's the delegate for the application, not a controller. Your controllers may be loaded from a xib by the time applicationDidFinishLaunching is called, but there's no connection between the two events.
applicationDidFinishLaunching is just the place where you do final setup before the app is ready for use.
If you don't instantiate your tab bar controller in your main xib file, you can instantiate it here, then instantiate all of it's controllers and add them to to the tab bar controller. While you're doing that, you can load plists, set properties on the controllers, etc.
If you do instantiate your tab bar controller in your main xib file, you can still get access to its controllers here. You can edit those controllers or throw them out and create new ones. You can even throw out your tab bar controller and switch to a navigation controller.
I can't answer questions 1 and 2 because the assumptions behind them are invalid.
Rather than ask how you work around perceived problems with the app delegate and tab bar controllers, describe what you're trying to accomplish.
I start off with a login screen. Then after the user logs in I load a Viewcontroller with UITabBArController in it. The problem is viewdidAppear: does not get called for any of the individual viewControllers in the tabBarController.
I have a feeling that this is not the best programming practise so does anyone have any ideas how to improve the structure of my code or how to fix my problem ?
I'd guess your trouble here comes from incorrect use of UIViewController and UITabBarController.
UITabBarController exists as a container for multiple view controllers. It probably should not, itself, be contained. It's designed to sit at the top of a view controller hierarchy. So step one is probably to re-arrange your application so that the UITabBarController is no longer under anything else and see if that straightens you out.
After that, slev's approach of presenting the login view sounds like the right one.
I had a problem because I was subclassing also UITabBarControler where I have overridden viewDidAppear without calling [super viewDidAppear:...]
After calling this, viewDidAppear was called also inside sub-view-controller.
Why not make an app which is TabBarController-based, then immediately call a modal screen at app start (for your login)? After you're done with the login, just dismiss it to allow the TabBarController to become key window.
You could try to manually call viewdidAppear on the subviewcontrollers: when it's called on the rootviewcontroller also call subviewcontroller's ones manually.
So I posted a question a while back which can be seen at: How to reset an iOS application when a user clicks the "sign out button"?
Following the advice I made a sign out button where a user where by is taken to the main screen where they can register or sign in again. What I am finding out is that when a new user signs in, I am seeing certain value from the old user in pickers, UITextView ETC
Is there a way to reset application state or do I have to go the long route of making sure that each outlet is set to default values? Is this a sign of bad programming practice somewhere?
The Cocoa way = KVO (key value observing). Controllers interested in being informed about login state change register themselves as observers on login component/controller/whatever instance does the login.
After login/logout this component notifies all observers about state change. Those then do all necessary actions: populating UI with user data after log in or resetting them after log out.
Very flexible pattern that avoids unnecessary dependencies between components.
Ok first thing you have to do is make your main view implement the delegate for signout successful. In this you got to reset all the data and views which will be recreated/repopulated when a new user signs in.
Inorder to achieve this you can analyse your code/logic as to what is created on a new user sign in and reset all these in the delegate method for sign out. This is way to generic an answer but resetting the data is the way to do it.
Alternatively you can recreate your main view when sign in is successful i.e. remove the main view and on sign in success create it afresh for the new user.
The cleanest way would be to create a new set of view controllers and set them to the viewControllers of the UITabBarController object but it needn't be the cheapest always. This will be something that you need to check if it's viable or not.
Otherwise, you'll have to to consider adding reset methods to the view controllers. If the tab is a navigation controller, popToRootViewControllerAnimated: and reset the first view controller. This one is a bit of effort to implement compared to the former approach.
When ever you go to new controller just allocate the whole controller again. and dont forget to release once the navigation is done.
Heres the sample code example to do it
-(void)goToFormController
{
FormViewController *objFormViewController = [[FormViewController alloc]initWithNibName:#"FormViewController" bundle:nil];
[self.navigationController pushViewController:objFormViewController animated:YES];
[objFormViewController release];
}
Happy iCoding...