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

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)

Related

How to make a delegate object accessible throughout a ViewController

I'm trying to get an instance of my AppDelegate accessible to all methods in each ViewController that I have. If I try to declare it with other class variables I get Initializer Element is not a compile-time constant. If I declare it in a method within the ViewController however I am able to use it. I am trying to save integers and floats to properties I have set up in the AppDelegate (a big no-no I know, but this is a project for an introductory class and I'm not expected to get too advanced, especially since everything we've done so far is not compliant with the MVC paradigm). The app uses a toolbar to switch between views using the app's ViewController to load the other ViewControllers as subviews. I was going to put the AppDelegate declaration and update statements in the ViewDidUnload method of each view controller, but I'm not sure that the Views are unloaded whenever they are switched (they're switched by removing the current View from the SuperView and loading the new one as a Subview at index 0). What happens to the views that are not currently being viewed then? Is there a method that detects that that I could implement the AppDelegate declaration and updates into?
I guess ideally I'd like to be able to access the AppDelegate object in any method in my ViewControllers because I have a lot of quantities being updated throughout and would like to have those quantities updated in the AppDelegates values as soon as they happen, since I'm not sure what happens with a View is cleared from SuperView
Thanks in advance everyone
You can access your app delegate via [[UIApplication sharedApplication] delegate] from anywhere in your application.
You should never instantiate another copy of the object on your own. The system does this for you at startup.
As for detecting changes, you can override the viewDidDisappear method of UIViewController. (You're correct--in general, they will not be unloaded when switched, and viewDidUnload will not be called)

How do you pass an object between ViewControllers on iOS?

Using the "Tab Bar" template in Xcode 4, each ViewController is created automatically, so I don't have the chance to set any properties on a ViewController as it's created. I want each ViewController to have access to an object (an instance of FMDB's FMDatabase).
There are a number of questions on StackOverflow relating to this already, but some are assuming that you are creating the VC's by hand, and others recommend using the AppDelegate as a mediator:
MyAppDelegateClass *appDelegate = [[UIApplication sharedApplicaton] delegate];
myLocalProperty = appDelegate.someDataModelProperty;
The above seems rather "hacky" to me. Is there a better way to access a single object from multiple ViewControllers?
Most probable implementation of FMDB's Data base would be to implement it as a Singleton and access it through out the application. Is there any reason for not doing so ?
This link should help you in doing so:
How do I make FMDB's database a singleton
To expand on KKK4SO's answer, you could implement the Database as a singleton. Then, have all of your UIViewControllers be a subclassed UIViewController that contains methods to access and modify the Database singleton.
MyAppDelegateClass *appDelegate = [[UIApplication sharedApplicaton] delegate];
myLocalProperty = appDelegate.someDataModelProperty;
There is a spelling error in this code 'sharedApplicaton' is incorrectly spelled it should be 'sharedApplication'.
Shame on me for copy and pasting! Anyway this will work for a quick and dirty way of passing data between ViewControllers etc.

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

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)

iPhone xcode - Best way to control audio from several view controllers

I am pretty new to iPhone programming.
I have a navBar with three views. I need to control audio from all of the views. I only want one audio stream to play at a time. I was thinking that it would be smart to let my AppDelegate have an instance of my audioplaying class and let the three other views use that instance to control the audio. My problem is that I donĀ“t know how my views can use the audioplaying class in my AppDelegate.
Is this the best approach and if so, how? Is there a better way?
The cleanest way would probably be to implement a singleton that you could access from all your view controllers (e.g. [[MYAudioController sharedController] theAudio]). It's also possible to access it in your app delegate (e.g. [(MYAppDelegate *)[[UIApplication sharedApplication] delegate] theAudio], but I tend to think it's a bad idea to make view controllers dependent on the app delegate.

iPhone: Using a Singleton with Tabview Controller and Navigation Controller

I have developed a small iPhone application by using singleton that I use to navigate through the views. Here is a sample method from my singleton class.
+ (void) loadMenuController:(NSMutableArray *)menuItems{
MenuViewController *menuViewControler = [[MenuViewController alloc] initWithNibName:#"MenuViewController" bundle:nil];
[menuViewControler setMenuItems:menuItems];
RootViewController *root = (
P2MAppDelegate *appDelegate = (P2MAppDelegate*) [[UIApplication sharedApplication] delegate];
UINavigationController *navController = [appDelegate navigationController];
[navController pushViewController:menuViewControler animated:YES];
[menuViewControler release];
}
Now my requirement has changed to require a tab view controller . I could change my application delegate to a tabview controller but I still need to navigate inside each tab. I am unable get a clue how to navigate from my singleton class.
Please guide me. Please let me know if my query is not clear.
Thanks in advance.
Regards,
Malleswar
You shouldn't be using a singleton to manage the interface and even if you did, you wouldn't put the UI logic in a class method. You need to rethink your design from scratch.
The normal pattern is to hold the navigation controller or the tabbar controller as an attribute of the application delegate. The app delegate itself should not be a subclass of any controller but just a NSObject subclass that implements the application delegate protocol.
Look at the Apple supplied template projects in Xcode to see the quick and dirty way to structure apps built around navigation and/or tabs.
Singletons should only be used when you have to ensure that one and only one instance of class is alive at one time. You don't need to make your own singleton to manage the UI. The application delegate is attached to the application object which is itself a singleton. This means the app delegate provides all the restriction on class for the UI you might need. You don't need another singleton in addition to that.
Overuse of singletons is dangerous and can cause your design to get trapped in a dead end resulting in a massive rewrite. Think carefully before employing them.