iPhone DropBox App Like implementation - flipping tab bar to reveal login screen - iphone

I am writing an application where you need to show login screen modally and the app has a tab bar.
I have added tab bar directly to the UIWindow. To flip it to a new view (login view) I have overridden applicationDidFinishLaunching where I check if user has login credentials, then I do not show the login screen otherwise (assuming first time use or logout case) I modally present the login screen. I have given an option of logout in a settings tab inside the app.
I am using [[UIApplication sharedApplication] delegate] call to get instance of app delegate when user logs in first time. This way I get access to the tabBarController that is part of the Application Delegate (as is most of the times). However, when I try to call my loginViewController from the logout option in settings (somewhere in future life cycle), the same call [[UIApplication sharedApplication] delegate] returns me a delegate on which I am not able to use any of the methods I have defined. It gives me "unrecognized selector sent to instance" error at runtime.
I need to understand what exactly the call [[UIApplication sharedApplication] delegate] returns? Does the delegate object it returns change over the period of application life cycle? OR is it a singleton instance through out the app life cycle?
And secondly to resolve this, should I add the tabBar to a view (contained in main window) instead of adding it directly to the UIWindow (as done by the template for Tab Bar application and seems to be the standard practice). Are there any known problems with this approach OR its okay to do so. Any one has tried this? Please let me know.
Thanks
Dev.

It sounds like your class that gets an instance of your singleton delegate doesn't know what it implements. make sure you are #importing your delegate to the class that uses it as [[UIApplication sharedApplication] delegate]. Also, if you get a warning about UIApplication not conforming or whatever, you can cast it to your AppDelegate type to avoid it.
To answer your question about what this call returns, it is a singleton throughout the lifecycle of the app.
To answer the 2nd question, having it in the UIWindow (and thus in the appdelegate) is fine, and probably encouraged, since it is the root controller of your app (from the sound of things)

Related

Should a global instace of a viewcontroller be owned by app delegate

Due to a bug/problem with ZBar and iOS 7 we can not create, destroy and recreate a view controller that's used for scanning. So we need to keep an permanent and global instance of it to be accessed by several different views.
In the current solution the scanner view instance is a member of the app delegate and instanciated when the application starts. When it needs to be displayed it is accessed by [[UIApplication sharedApplication] delegate].
This is a forced solution but I still want it to be as descent as possible. Is there a better place to put the scanner view controller?
Make a Singleton class for your scanning
Better you put in .pch file,
#define MY_APP_DELEGATE ((AppDelegate *)[UIApplication sharedApplication].delegate)

Receiver type for instance message is a forward declaration popToRootViewController

I've seen similar questions on this error.
But I'm not sure how it applies in this instance
This is the error
Receiver type for instance message is a forward declaration
And this is my code.
MyAppDelegate *appDel = (MyAppDelegate*)
[[UIApplication sharedApplication] delegate];
[appDel.secondTabNavController popToRootViewControllerAnimated:NO];
What's the problem here and how do I fix it ?
I clarified my usage of this code was correct, as a different navigation controller for each of my tabs in my tab controller. I do this as I push views within each controller.
Several UINavigation controllers, one for each tab, as an outlets from my app delegate?
Try to import the appdelegate.h and it should work fine.
A better way of implementing this would be to use notifications.
1. Send a notification when you reach the condition
2. Handle the notification in the appropriate view controller. (You can handle it in the app delegate too but it is not a clean way)

Switch between view without closing view xcode

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.

Save data to a navigation controller for access all throughout the application

First i was wondering if this is a good idea, essentially i have user class and throughout the application i would have a current user and various views would want to access this users data. would it make sense to store this user in the navigation controller so that each class can access it without having to pass it through the prepareforsegue on every view?
Second if this is ok to do, how do i access a variable in the navigation controller? i have it setup so it has one called _myUser just like i would in the other views but how do i call/set that from a view?
I would recommend saving data to either your application delegate or if it starts to get messy creating a singleton. The application delegate is a better practice and can be shared throughout your app easily. You can access it easily with something like this:
YourAppDelegate * del = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
NSLog(#"%#", del.yourPropertyToShare);

applicationWillTerminate, delegate or view?

I am looking to save some settings when my application exits and I am a little confused about the 2 different versions below. My feeling is that to better fit the MVC pattern I should be using the version in the viewController. I am just curious as most folks don't seem to do much in the appDelegate when that call would be used?
AppDelegate
-(void)applicationWillTerminate:(UIApplication *)application {
NSLog(#"_deli: applicationWillTerminate");
}
ViewController
-(void)applicationWillTerminate:(NSNotification *)notification {
NSLog(#"_view: applicationWillTerminate");
}
many thanks
EDIT_001:
Sorry, I should claifiy, you would also need to add (see below) to the ViewController to make the above work.
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationWillTerminate:)
name:UIApplicationWillTerminateNotification
object:app];
gary
Use whichever one has access to the data you want to save. So if the ViewController can see the data but the AppDelegate can't, use that.
Well, to flog my personal hobby horse, I would say that settings are a form of preferences that should be saved in a dedicated data model. NSUserDefaults, for example, is a data model built on the singleton pattern. You could, of course roll your own. There is no problem with having multiple data models in the same app if they manage unrelated information.
The key is to save defaults/preference/state as they are made. Then when the application quits the defaults are already automatically saved. Remember that on the iPhone you never know when the app will be interrupted or quit. Save as you go is really the only option.
Also, in the code examples you provided, how will the view controller know when the application quits? IIRC, UIViewController does not have a applicationWillTerminate: method and does not automatically receive a specific app will quit message. (Edit: In the comments, KennyTM points out that the view controller can register and listen for UIApplicationWillTerminateNotification) You would have to put this functionality in -viewWillUnload. Otherwise, you would have to track your view controllers from the app delegate have the delegate send the active view controller a message when the app quit.