Refer to an integer from one ViewController from another - iphone

I'm unable to refer to my integer pickedItem declared in my RootViewController.h in my DetailViewController.m file.
Not sure if I should declare this as a global variable, but tried unsuccessfully to do so.
I think this should be simple, but I haven't got any other suggestions (from other posted answers) to work.
Thanks in advance.

You can access the app delegate through [[UIApplication sharedApplication] delegate] this call. And then can access the root view controller's property (assuming you have access to the rootViewController object in appDelagate).
In RootViewController.h
#property(nonatomic, assign) NSInteger myInt
And from anywhere in the code
UIApplicationDelegate *delegate = [[UIApplication sharedApplication] delegate];
delegate.viewController.myInt = 31;
p.s. I have just typed the code, not compiled. So there might be some typo.

You just wouldn't want it coded this way. I recommend taking a look at NSNotificationCenter, or create a delegate class for yourself, to communicate to the DetailViewController of page changes. There shouldn't be a dependency from detail -> root the way you have it.
Based on your code above, I don't see where you're setting rootViewController on detailViewController? Is it nil? I'd think referencing rootViewController.pickedItem if rootViewController was nil would cause a crash, but worth checking.
Also, is pickedItem being set appropriately? In other words, is it set before the detail code is being called?

Related

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 access a property value from AppDelegate

How to access a property value of AppDelegate class from someView Controller without creating reference of the delegate in view controller?
I'm not quite sure what you mean - there are multiple ways to get information from your application delegate into a view controller, and the phrase "without creating reference of the delegate" is unclear. Your options basically are:
Reference the application delegate, casting as appropriate. You would write code in your view controller class like: id propertyValue = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] myProperty];
Pass the property in when creating the view controller. This requires the view controller to have a #property declared and #synthesized for use, then you would have the app delegate just set the property on the view controller instance.
Neither of these options require that you retain a copy of your app's delegate as a #property, but the first does reference the delegate once.
[UIApplication sharedApplication].delegate
You'll also need to include the app delegate header file in your view controller and possibly typecast the delegate from id to your actual app delegate class.
#include "MyAppDelegate.h"
((MyAppDelegate *)[UIApplication sharedApplication].delegate).myProperty;
[UIApplication sharedApplication].delegate;

iPhone MVC app: Where should I put the model?

I'm pretty new to iPhone development.
I am building an app which has multiple views and controllers. There is only one model.
I need to share the model amongst all of the controllers; so I have instantiated the model inside the App Delegate header file:
#interface MyAppDelegate
(...snip...)
#property (nonatomic, retain) CalcModel *model;
and then synthesized it accordingly.
Inside a controller, I have tried to reference the model like so:
CalcModel* model = [[[UIApplication sharedApplication] delegate] model];
The problem is that the compiler says '-model' not found in protocol
This is probably because the delegate field returns the protocol type, not the concrete MyAppDelegate type... so should I cast [[UIApplication sharedApplication] delegate] to MyAppDelegate, so I can access the model property? If so, how?
Or is this all wrong? More broadly, how would you share a model amongst view controllers?
many thanks for your help
Yes, just cast it. I #define a macro that wraps this into a simple call to make it easier.
With regard to one way to implement the model structure, there are some useful pointers in this article:
http://www.bit-101.com/blog/?p=1969
(We just implement models as singletons themselves, and use KVO from the views to listen for changes to properties.)
You can typecast it just like you typecast any other object
CalcModel* model = (MyAppDelegate *)[[[UIApplication sharedApplication] delegate] model];
you'll have to instanciate the model in you appdelegate .m

Call AppDelegate Method from Class

Basically, I need to call a method in my AppDelegate from one of my view controller classes.
Currently, I'm doing the following:
myAppDelegate *appDelegate = (myAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate doMethod];
And including the myAppDelegate.h at the top of the .m file of the class:
#import "myAppDelegate.h"
When I run it, everything works...
But I get the following warning:
warning 'myAppDelegate' may not respond to '-doMethod'
Is there another way that I should reference the app delegate?
Thanks for any help in advance.
EDIT: FIXED:
All I had to do was declare the method in the .h file of the AppDelegate:
-(void)doMethod;
adding to Marks comment. Is the -(void) doMethod; declared in the appDelegate header file and is the appDelegate.h file imported in the file you try to call the method from:)
Sorry should have put it in as an answer in the first place, so the question does not look unanswered :/

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.