How do you pass an object between ViewControllers on iOS? - iphone

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.

Related

I want to store a bunch of data in an array, for use in various different classes. How?

So i've tried and tried at this and for the most part it's worked, but with it's problems. I need to start again though with this. So can somebody explain the best way that I can have an array in my app which allows other classes to access it, edit it, delete items from it and add new items?
You can probably have it declared as an instance variable in appDelegate so it can be easily accessed by other classes
YourAppDelegate *appDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
//and then access the variable by appDelegate.variable
If u declare array in the appDelegate you can access the array in all other classes using main appDelegate instance.

Core Data - Basic Questions

I would like to know how the following works in Objective-C
in my header file i have the following which is initialized from a different view controller
#interface UserLookup : UIViewController {
NSManagedObjectContext *referringObject;
}
and in my implementation file i have to pass this NSManagedObjectContext to 2 child view controller then does it make a difference which view controller is called first... and does the NSManagedObjectContext changes in any one of the child controller?
Regards
You don't really need to pass it around to every view controller where you will need Core Data access - just use
NSManagedObjectContext* moc = [(MyAppDelegateClass *)[[UIApplication sharedApplication] delegate] managedObjectContext];
managedObjectContext must be an accessible ivar of your app delegate.
It makes it conceptually similar too. There is one NSManagedObjectContext (in most uncomplicated apps, thought you can have multiples), owned by your app delegate. You don't ever retain or release it (except for when it is created in the app delegate, on first access if you are using Apple's template code, and when it is released in app delegate's dealloc.
ASFAIK it should not make a difference which viewController is used first. Think of the NSManagedObjectContext as a pointer to the physical datasource.
You can add and remove NSManagedObjects from the context. But these changes are only saved to disk when you call the save: method.
Does that help at all?
To use only one context is simple and works fine. But you can also create a new managed object context and pass it to the other view controller. Though the persistent store is only one, but you can have multiple contexts.
Each context have each undo manager, so you can control changes of managed objects in the context. You can save changes in only one context even if the other context has also some changes. After saving a context, you can merge the changes of two contexts by the following NSManagedObjectContext instance methods:
- (void)mergeChangesFromContextDidSaveNotification:(NSNotification *)notification
- (void)refreshObject:(NSManagedObject *)object mergeChanges:(BOOL)flag
Maybe this document helps you to understand more detail.
http://developer.apple.com/library/ios/#documentation/DataManagement/Conceptual/CoreDataSnippets/Articles/stack.html
And the CoreDataBooks Apple sample code uses the additional context.

how to get to appdelegate from viewcontrollers' value?

i know how to access appdelegate's value inside Viewcontroller like
YourDelegate *appDelegate = (YourDelegate *)[[UIApplication sharedApplication] delegate];
but i want simple method like this when i want to get value from viewcontroller to appdelegate(reverse order).....? any help...?
suppose if i have one method in appdelate. i want to get data value from view controller page,i want to use it in appdelegte.m file.......?
To address this question more generally...If you want to do anything with an object – send it a message (call a method on an object), access some property of an object, pass the object as a parameter to some other method – you need a reference to that object.
That means that, in your case, your AppDelegate needs a reference to the view controller you want to access some property of. If the view controller is allocated and initialized in your app delegate, this is as simple as storing a reference to said view controller in your delegate until you need to use it (using an instance variable or whatever). If it wasn't, then you need to do something else to get your app delegate a reference to the view controller – the steps to do this would depend on where and how the view controller was created. Without more specific details, I can't help you with those steps.
Model-View-Controller (MVC) Sidenote:
If you are following MVC design practices, a view controller (or any other controller class) is not the object that should be storing your state information or other application data. That job is supposed to be performed by a model object.
Make the method be a class method (declared with + (void) MyMethod: (int)myParameter) and call it from your app delegate like this: [MyOtherViewController MyMethod: myParameter].
This to call checkAppTheme method from AppDelegate.m :
[(AppDelegate *)[[UIApplication sharedApplication] delegate] checkAppTheme];
Don't miss to change (checkAppTheme) to your method in your AppDelegate.m
Good luck!

what is applicationDelegate - iPhone

(WebService_1AppDelegate*)[[UIApplication sharedApplication] delegate]
here - in above statement "WebService_1AppDelegate" is my application name.
But i don't understand what does this statement mean.
Please explain me - briefly this statement.
I will be thankful.
Thanks in advance for helping me.
An AppDelegate is a singleton that every iPhone program has. This class is responsible for receiving many system calls such as applicationDidFinishLaunching, applicationWillTerminate etc. It is the entry point for an iPhone app.
Each app defines their own AppDelegate and thus WebService_1AppDelegate is yours. You can define your own methods/properties there and when required cast the AppDelegate returned from [UIApplication sharedApplication] to access your methods/properties.
WebService_1AppDelegat *appDelegate = (WebService_1AppDelegate*)[[UIApplication sharedApplication] delegate];
[appDelegate yourCustomMethod];
That statement only make sense if you have a class named WebService_1AppDelegate. Then it's casting the return value of that method (which is the application delegate) to that type. If that is indeed the name of your application delegate class then that cast is superfulous,
Are you trying to figure out what "AppDelegate" is in an iPhone app? If so, AppDelegate acts as a central storage medium for your application that allows you to share data across all of your controllers seamlessly. If you're familiar with web development it is just like a Session variable.

Best Application Delegate Practice

I have been making a few apps here and there, and I know my way around. What has always confused me is accessing global attributes, and where the best place to set them are. I have a few questions about accessing things and how to access them.
Do you have to include your application delegates header file into any other other file you want to access it in? Say I have a view controller, that I would like to use, do I need to include the .h inside my view controller's .h? Or can I set the:
#class AppDelegate;
Can you only access the delegate by typing out:
[UIApplication sharedApplication].delegate
EACH and every time? Is that something I just have to get used to? Or could I set the following in my implementation in each .h:
AppDelegate *delegate;
And inside the init function, put the singleton instance to that variable?
Sorry if this was off structure, but I think it's a logical question people have a problem encountering and solving.
Maybe you need to reconsider how you are using the App Delegate? It sounds to me like perhaps you are not making a very good class design.
Regardless, here's a way to make it easy. Don't put this in init just use it when you need it.
MyAppDelegate *delegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
Naturally, replace MyAppDelegate with the actual class name of your app delegate.
Another possibility is to add the code to use a properly casted app delegate reference as a #define in the app delegate header file, so after including it you can do something like:
MYAPPDELEGATE.customProperty = blah;
However I tend to favor just writing out the line that John presented, as use of #defines confuses code completion which I find more annoying than just typing the line.
As also mentioned, if you have a ton of references to the app delegate you may want to restructure to keep some of those references closer to home.