Please do not post the same thing multiple times. The board software automatically flags certain posts as needing moderator attention. This happens the most often for new users. I'm pretty sure this is made clear at the time you attempt to post. Posting the same thing over and over again just makes that many more posts the moderators have to weed through later. This makes us sad. Don't make us sad. If your post/thread doesn't appear, just wait a while. Don't post it again. If it hasn't shown up by the next day, then you can try again. I normally go through posts in the mornings, and try to check a few times throughout the day, but I'm not here 24/7. There will typically be a significant delay before posts are approved. Just be patient.
Sharing data between view controllers and other objects - link fixed
At least a couple of times a week somebody posts a question something like this:
My app has 2 view controllers, and I need to get information from the user in one view controller, and pass it to a second view controller. How do I do that?
More generally, the question is, what's the best way to share information between different objects in your app?
I got tired of answering this question repeatedly, and decided to write a sample app that shows how to do it. The idea is to create a single data container object that is a property of the app delegate, and make that data object available to every object in your app that needs it.
Here's what I did:
-I created a generic data container class AppDataObject. This is an ancestor class for a data container object that you would actually use to hold your application's global variables.
-At init time, I added code to the app delegate that create an empty data container object.
-I created a dirt simple protocol, AppDelegateProtocol. This protocol only lists one method, -theAppDataObject. That method lets you ask the app delegate for it's data object.
-I created a subclass of the AppDataObject that actually holds data for a real app. This is where you put the information that you want to share between objects.
Using a protocol means that the only things the objects in your app need to include are the AppDelegateProtocol and the header for your subclass of the app data object. You don't have to #include the header of your app delegate, which makes for good separation between the different objects in your app.
I have posted a complete project, ViewControllerDataSharing, that uses the above method to share information between view controllers. The project uses a navigation controller, and has a root view controller and a second view controller. Each view controller has a UITextView and a slider. The app uses an AppDataObject to pass the value of these fields between view controllers.
I've posted the project to my public iDisk. You should be able to download it simply by clicking the link below:
Wouldn't it be easier to use NSUserDefaults to simply save and retrieve data across viewControllers? That way you would also already have a basic data saving and retrieval method for loading saved games.
Nathan Stoltenberg
Lead Programmer - Fractal Fox Studios
Mobile Applications Consultant - The Principal Consulting
Wouldn't it be easier to use NSUserDefaults to simply save and retrieve data across viewControllers? That way you would also already have a basic data saving and retrieval method for loading saved games.
If your data includes custom classes, this will not work. You'd have to convert those objects to something that could go into NSUserDefaults - like a dictionary - and then convert back on the other end. Not worth the effort, and will be significantly slower than simply passing a reference.
Wouldn't it be easier to use NSUserDefaults to simply save and retrieve data across viewControllers? That way you would also already have a basic data saving and retrieval method for loading saved games.
Sorry, but using a disk based persistent store to exchange in-memory values between objects in a running program seems really, really dumb.
As a friend of mine says, it "seems like a reaching around your elbow to scratch your butt way to go."
All you need to do is have one view controller have a pointer to the other, or better yet, to a shared data container object.
As Brian explains later, userDefaults also doesn't work for anything other than "plist" data structures (NSDictionaries, NSArrays, NSNumbers (and other NSValue objects) and NSData.)
Regards,
Duncan C WareTo
Animated GIF created with Face Dancer, available for free in the app store.
At this point I'm not sharing that sort of data (CGPoints for example), so It didn't make sense to take the extra work to create a data class for things easily stored such as strings, urls, integers, and arrays. This is an amazing solution for more complicated sharing between objects. Thanks for opening my eyes.
Nathan Stoltenberg
Lead Programmer - Fractal Fox Studios
Mobile Applications Consultant - The Principal Consulting
Nice and clean. However my singleton pattern works like a dream. I know it's not the cleanest way to go and I'll try to get into your way of coding as it seems nice but it'll be painful to drop my singleton! So simple...
Nice and clean. However my singleton pattern works like a dream. I know it's not the cleanest way to go and I'll try to get into your way of coding as it seems nice but it'll be painful to drop my singleton! So simple...
Nobody says you need to. I use singletons all the time. Every major app I've done has a DataController class.
Nobody says you need to. I use singletons all the time. Every major app I've done has a DataController class.
Yeah I've never understood why people hate the singleton pattern so much. Possibly because you have an instance of an object that never gets released and sits in memory all the time but to be honest, I NEED that data all the time anyway so I don't want to release it! A singleton populated with value objects and a few methods to grab value objects by id etc works like a charm. I'd recommend that approach to anyone.
This code is well written and does nearly exactly what I was looking to do (i.e. share data between two viewcontrollers). One question though... Is there a way to push the data from one controller to the other when it changes?
I have two view controllers that are displayed simultaneously, therefore, the -(void)viewWillAppear:(BOOL)animated method doesn't really help me out.
My gut tells me that I may need to set up a notification center. Just wondering if there is a better/cleaner way to do this.
Thank you so much for doing this. This is exactly what I have been looking for and I appreciate you taking the time to explain it and show it. Thanks again for all you do and all your help.
This code is well written and does nearly exactly what I was looking to do (i.e. share data between two viewcontrollers). One question though... Is there a way to push the data from one controller to the other when it changes?
I have two view controllers that are displayed simultaneously, therefore, the -(void)viewWillAppear:(BOOL)animated method doesn't really help me out.
My gut tells me that I may need to set up a notification center. Just wondering if there is a better/cleaner way to do this.
Thanks, Jameson
Jameson,
Actually, there is an Apple technology that's tailor-made for what you want: KVO (Key Value Observing)
Do a search on "Key-Value Observing Quick Start" in the XCode help system for more info.
You would want to make objects that need to be notified of changes call observeValueForKeyPath:ofObject:change:context: on the data container object. Then, they will get notified automatically when the object changes.
That's a good idea for an extension for my sample project. I'll think about adding KVO to it if I get some time.
Regards,
Duncan C WareTo
Animated GIF created with Face Dancer, available for free in the app store.
At least a couple of times a week somebody posts a question something like this:
My app has 2 view controllers, and I need to get information from the user in one view controller, and pass it to a second view controller. How do I do that?
More generally, the question is, what's the best way to share information between different objects in your app?
I got tired of answering this question repeatedly, and decided to write a sample app that shows how to do it. The idea is to create a single data container object that is a property of the app delegate, and make that data object available to every object in your app that needs it.
Here's what I did:
-I created a generic data container class AppDataObject. This is an ancestor class for a data container object that you would actually use to hold your application's global variables.
-At init time, I added code to the app delegate that create an empty data container object.
-I created a dirt simple protocol, AppDelegateProtocol. This protocol only lists one method, -theAppDataObject. That method lets you ask the app delegate for it's data object.
-I created a subclass of the AppDataObject that actually holds data for a real app. This is where you put the information that you want to share between objects.
Using a protocol means that the only things the objects in your app need to include are the AppDelegateProtocol and the header for your subclass of the app data object. You don't have to #include the header of your app delegate, which makes for good separation between the different objects in your app.
I have posted a complete project, ViewControllerDataSharing, that uses the above method to share information between view controllers. The project uses a navigation controller, and has a root view controller and a second view controller. Each view controller has a UITextView and a slider. The app uses an AppDataObject to pass the value of these fields between view controllers.
I've posted the project to my public iDisk. You should be able to download it simply by clicking the link below:
Hi Duncan and all of the members, I´ve used your code in an iPad app. Works perfectly, but now I´ve added a navigationcontroller that loads viewcontrollers for each screen. It crashes when I access the theDataObject.string1 on the viewcontrollers pushed by the navigationcontroller.
It´s quite strange, because I´m using it without problems using tabBarController in other screens of the app, but when I change to this navigationcontroller crashes.
Any idea? Anyway, thanks for your help and your great code.
As an unabashed cut-and-paste programmer (with just enough experience in Java to be dangerous), thank you! I was going to go the "quick and dirty" route, but I try to learn one or two new skills with each new app, and this worked beautifully!
Of course, I understand maybe 50% of what it all does, but, hey, it works and I'm that much closer to completing my second app. I want you to know how much I appreciate the code that you posted and how helpful it has been to me.
Hi Duncan and all of the members, I´ve used your code in an iPad app. Works perfectly, but now I´ve added a navigationcontroller that loads viewcontrollers for each screen. It crashes when I access the theDataObject.string1 on the viewcontrollers pushed by the navigationcontroller.
It´s quite strange, because I´m using it without problems using tabBarController in other screens of the app, but when I change to this navigationcontroller crashes.
Any idea? Anyway, thanks for your help and your great code.
Sorry, I missed this post until now.
You probably have an over-release problem. You'd have to post the offending code in order for us to be any help finding the problem.
Regards,
Duncan C WareTo
Animated GIF created with Face Dancer, available for free in the app store.
Hi Duncan C . Can you give an example for sharing UISwitch value between view controller ? I want to pass uiswitch value from settings view to gameview (EAGLView) to turn background music on/off. Thank you.
Duncan C;228133 said:
At least a couple of times a week somebody posts a question something like this:
My app has 2 view controllers, and I need to get information from the user in one view controller, and pass it to a second view controller. How do I do that?
More generally, the question is, what's the best way to share information between different objects in your app?
I got tired of answering this question repeatedly, and decided to write a sample app that shows how to do it. The idea is to create a single data container object that is a property of the app delegate, and make that data object available to every object in your app that needs it.
Here's what I did:
-I created a generic data container class AppDataObject. This is an ancestor class for a data container object that you would actually use to hold your application's global variables.
-At init time, I added code to the app delegate that create an empty data container object.
-I created a dirt simple protocol, AppDelegateProtocol. This protocol only lists one method, -theAppDataObject. That method lets you ask the app delegate for it's data object.
-I created a subclass of the AppDataObject that actually holds data for a real app. This is where you put the information that you want to share between objects.
Using a protocol means that the only things the objects in your app need to include are the AppDelegateProtocol and the header for your subclass of the app data object. You don't have to #include the header of your app delegate, which makes for good separation between the different objects in your app.
I have posted a complete project, ViewControllerDataSharing, that uses the above method to share information between view controllers. The project uses a navigation controller, and has a root view controller and a second view controller. Each view controller has a UITextView and a slider. The app uses an AppDataObject to pass the value of these fields between view controllers.
I've posted the project to my public iDisk. You should be able to download it simply by clicking the link below:
I was looking for such a sample for a long time. Your sample helps me lot without any problem. I have used your delegate to pass device location between background process and mapview.
Replies
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeLead Programmer - Fractal Fox Studios
Mobile Applications Consultant - The Principal Consulting
Apps I've coded:
http://www.fractalfox.com/Fractal_Fox/Games.html
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeSlickShopper 2 | BTIConcepts on GitHub | Free NSLog utility | Free Getter Utility | Leave a PayPal donation.
Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | A Model (Object) Is A Beautiful Thing
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeAs a friend of mine says, it "seems like a reaching around your elbow to scratch your butt way to go."
All you need to do is have one view controller have a pointer to the other, or better yet, to a shared data container object.
As Brian explains later, userDefaults also doesn't work for anything other than "plist" data structures (NSDictionaries, NSArrays, NSNumbers (and other NSValue objects) and NSData.)
Duncan C
WareTo
Animated GIF created with Face Dancer, available for free in the app store.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeLead Programmer - Fractal Fox Studios
Mobile Applications Consultant - The Principal Consulting
Apps I've coded:
http://www.fractalfox.com/Fractal_Fox/Games.html
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeThe property self.theAppDataObject is set up as a retained property.
So, assigning something to that property causes it to be retained.
Thus, I release it so ONLY the property retains it. If I set the property to nil, the object gets released.
Duncan C
WareTo
Animated GIF created with Face Dancer, available for free in the app store.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesomejust wasn't thinking about the property.
thanks.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeOops. My mistake.
The .h file for ExampleDataObject is missing an instance variable. It should look like this:
(The missing line is marked in bold)
Duncan C
WareTo
Animated GIF created with Face Dancer, available for free in the app store.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeSlickShopper 2 | BTIConcepts on GitHub | Free NSLog utility | Free Getter Utility | Leave a PayPal donation.
Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | A Model (Object) Is A Beautiful Thing
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeThis code is well written and does nearly exactly what I was looking to do (i.e. share data between two viewcontrollers). One question though... Is there a way to push the data from one controller to the other when it changes?
I have two view controllers that are displayed simultaneously, therefore, the -(void)viewWillAppear:(BOOL)animated method doesn't really help me out.
My gut tells me that I may need to set up a notification center. Just wondering if there is a better/cleaner way to do this.
Thanks,
Jameson
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeThank you so much for doing this. This is exactly what I have been looking for and I appreciate you taking the time to explain it and show it. Thanks again for all you do and all your help.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeJameson,
Actually, there is an Apple technology that's tailor-made for what you want: KVO (Key Value Observing)
Do a search on "Key-Value Observing Quick Start" in the XCode help system for more info.
You would want to make objects that need to be notified of changes call observeValueForKeyPath:ofObject:change:context: on the data container object. Then, they will get notified automatically when the object changes.
That's a good idea for an extension for my sample project. I'll think about adding KVO to it if I get some time.
Duncan C
WareTo
Animated GIF created with Face Dancer, available for free in the app store.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeI downloaded the file and ran it -- it leaks memory -- is there a way to fix this?
Thanks
H
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeIt´s quite strange, because I´m using it without problems using tabBarController in other screens of the app, but when I change to this navigationcontroller crashes.
Any idea? Anyway, thanks for your help and your great code.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeOf course, I understand maybe 50% of what it all does, but, hey, it works and I'm that much closer to completing my second app. I want you to know how much I appreciate the code that you posted and how helpful it has been to me.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeYou probably have an over-release problem. You'd have to post the offending code in order for us to be any help finding the problem.
Duncan C
WareTo
Animated GIF created with Face Dancer, available for free in the app store.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeCan you give an example for sharing UISwitch value between view controller ?
I want to pass uiswitch value from settings view to gameview (EAGLView) to turn background music on/off.
Thank you.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesomefirst of all a big thanks for the helpful work you putted in here.
I have a short question regarding the object data sharing in an TabBar Application.
When I try to implement the code in the root view controller:
I get the following error in the first line of the method: Any ideas what could be the reason for this error?
Again thank you very much and have a nice day,
- MrBr.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeI was looking for such a sample for a long time. Your sample helps me lot without any problem. I have used your delegate to pass device location between background process and mapview.
Thanks again.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome