how to get managedObjectContext to work in multiple views - ios

I am having trouble accessing my coredata objects from multiple views and have read that you have to declare it in your app delegate differently.. But I havent found an example that makes sense to me yet.
This is how I am currently declaring it in my app delegate.
//try setting up context for coredata
EResponses *eResponses = [EResponses sharedManager];
eResponses.managedObjectContext = self.managedObjectContext;
I am wondering how I could get this to work for multiple views? Any help would be appreciated.

Either you can reference it from the application delegate (like you are doing).
Or you can setup a singleton class that holds the managed object context. That's how I'm doing it. I'm having a singleton class with all the Core Data functionality adn whenever I need to do some database manipulation I use my Core Data singleton class.

Related

Have multiple instances of a class point to one object #property

I will try to make this question as understandable as possible. I am implementing core data in my app, and I need to access the NSManagedObjectContext from around 10,000 different instances of a class (this class extends UIView). The Core Data stores what is displayed on these instances and the class builds it.
Everything that I have found so far uses View Controllers, of which you only have one instance, so you can just alloc init the VC in AppDelegate, set an #property for NSManagedObjectContext and be on your way. This does not work for my program.
What I want to do is have many instances of my CoreDataHelper class (which I will alloc init in the class that I have around 10,000 instances of, which all have a property pointing to the same NSManagedObjectContext. Is this a possible way to do it or will I have to make my program less flexible by moving all of the code to create the 10,000 different objects to the View Controller?
Sure, just put your NSManagedObjectContext in a singleton and all your instances can access the single class.
It does not matter if you get your managed object context from a singleton or from your app delegate (where presumably you the core data stack is set up by default).
To follow the pattern suggested by Apple with view controllers, do the exact same thing with your views: give them a #property of type NSManagedObjectContext and set it during initialization. Seems straight forward enough.
The advantage of the singleton is that you do not even need the property on your view but can call the singleton instead. But why go there? From your comments I understand that you do not really know how a singleton works. You don't need it. Go with the class property solution.
One more caveat: with your setup, you are seriously braking the MVC architecture by giving the views access to your data. Instead, you should indeed have a view controller do this and then populate your views with the retrieved data. I do not think that there is a compelling reason to deviate from this principle.

Casting of [UIApplication sharedApplication].delegate

I've got a test project to use the private data object on several view controller.
(I've downloaded it from web & git-hub)
- (ExampleAppDataObject*) theAppDataObject;
{
id<AppDelegateProtocol> theDelegate = (id<AppDelegateProtocol>) [UIApplication sharedApplication].delegate;
ExampleAppDataObject* theDataObject;
theDataObject = (ExampleAppDataObject*) theDelegate.theAppDataObject;
return theDataObject;
}
First question is, theDelegate was casted with AppDelegateProtocol, even this applications UIApplication delegate name was ViewControllerDataSharingAppDelegate, and there's no warning. I can't under stand why, maybe it's because that was a id type?
(AppDelegateProtocol is a custom delegate protocol he declared in the AppDelegate.)
Second, it shows this kind of code on every view controller, and it seems like just a single-ton pattern.
I don't think this is not the best way to transfer data between view controller.
Which is the best way to transfer object data type?
Thanks.
Creating a protocol decouples the code somewhat from the specific implementation. You could conceivably have several applications, each of which uses its own custom class as an app delegate, but all implementations conform to the AppDelegateProtocol.
I used to use the app delegate to hold global data and methods a lot when I first started in iOS.
However, that fills your app delegate with app-specific code.
I've shifted away from that approach recently, and use a data container singleton (and perhaps a utility methods singleton as well.) As is typical for a singleton, I define a class method that lets me fetch the singleton. I add properties to my singleton as needed to store data, and then just use the class method to get a pointer to the singleton. I write my class method to lazy load the singleton.
Its also easy to make your data container singleton persistent by making it conform to NSCoding. Then every time you get moved to the background, just save your singleton somewhere. On app launch, read it in.

iOS Singleton For Object storage

When I first created my app, I stored all my runtime custom objects and properties in my app delegate so I could share them across views. I never liked this and always wanted to change it so I did some reading today and moved all my runtime properties and objects to a singleton object like so:
#synthesize gblStr;
+(AppDataSingleton *)singleObj
{
static AppDataSingleton * single=nil;
#synchronized(self)
{
if(!single)
{
single = [[AppDataSingleton alloc] init];
}
}
return single;
}
where lets say gblStr can be accessed from any view controller that has the singleton.
This works great and I now have all my objects stored here instead of in my app delegate.
In each view controller I add the property:
AppDataSingleton *globalSingleton;
and in the viewDidLoad, I instantiate it:
globalSingleton = [AppDataSingleton singleObj];
MY QUESTION IS:
Will there ever be a case where a user will come back to the app and the singleton has been destroyed? Do I need to check for this?
Or, in the case it was destroyed, will it start the app over from scratch?
The singleton will be destroyed, if the app has crashes or stops running. Unless you write your objects to a persistent store (CoreData, .plist, SQLite, etc...), you will have to recreate your objects as well...
In my view, the singleton should persist for the life of the program run (i.e. an entire session). If you are not clearing it actively, that data should be there whenever the app returns from an inactive state. In any case, you are checking if the object is nil and reinstantiating if it is, so the data should be rehydrated.
If you have concerns about data not being there, you should be actively persisting it to CoreData or the sandbox.

Recipes to pass NSManagedObjects amongs UIViewControllers

Within an application it's possible to have different UIViewControllers that need to share the same NSManagedObject. I'm usually do the following:
#interface CustomController : UIViewController
#property (nonatomic, retain) ProductNSManagedObject* productManaged;
#end
Then when I istantiate CustomController I inject it like the following:
customController.productManaged = ....
once done, CustomController is responsible to release it.
This approach works well (I don't know if is it correct), but what to do when a controller need that object but it's not a direct child of the controller that has that object? e.g.
MainController -> ChildController -> SubChildController -> ....
where MainController has the managed object.
Do I have to create a lot of intermediary properties or do I need to execute a fresh NSFetchRequest or something else?
The same aspect could be applied to the NSManagedObjectContext. Searching around I've found that the context can be grabbed from the application delegate that posseses it (if any). But this approach lacks of flexibility as Marcus Zarra wrote in passing-around-a-nsmanagedobjectcontext-on-the-iphone.
Any suggestions? Thank you in advance.
I create a singleton object that contains the managed object context that will be used throughout the application. I put any supporting code related to the data (e.g., persistent store coordinator) inside this singleton and keep all of the view and controller information separated from it.
In one case, I need a managed object context for another thread. It became apparent that it would be useful to refactor and put that context inside the same singleton. Then merging between the two contexts can be done inside the singleton.
This has helped me manage my code. You might consider it.
This is a very common question (see here and here for related ones). As I wrote in the answers for the related questions, you should stay away from singletons and create a separate object that will take care of object instantiation, of creating the object graph for your application. This separate object can hold references to all shared objects and supply them to the objects being built, so that none of your regular objects has to keep a reference to something just to pass it as a dependency to other objects. See this blog post for more rationale against singleton misuse and for further pointers, especially the articles by Miško Hevery.
I have created a sample Xcode project that shows how to wire an app without singletons, keeping the coupling low and resolving other singleton issues. It’s very simple at the moment, I will add more common use cases later.

How to control data flow between ViewControllers

I'll start by saying I'm new to Objective-C and iPhone but I have history in C++, Java, AS3, ...
I'm trying to build some sort of RSS Reader, and I have an array for all my feeds. How is the best approach to save new feeds to this array? I have a navigation based project, and I have an add button which pushes a viewController on top to enter new feed URL.
But how do I save this back to the array in my other ViewController? Do I need to research more into SQLLite? Or set some delegates? Or Core Data?
I prefer the singleton method myself but Apple recommends dependency injection i.e. passing a data model object from view controller to view controller as needed.
If you look at a Core Data utilizing template navigation project in Xcode, you can see how this works. The managedObject context is the data model and it is initialized and held by the app delegate. You can then access it two ways:
(1) Since the Application instances itself is a singleton, you can ask it for its delegate and then ask the delegate for its managedObjectContest property. So, in a view controller you would have a property managedObjectContext with a custom getter defined like:
(NSManagedObjectContext *) managedObjectContext{
if (managedObjectContext !=nil){
return managedObjectContext;
}
// this is basically applicationObject.delegate.managedObjectContext
self.managedObjectContext=[[[NSApplication sharedApplication] delegate] managedObjectContext];
return managedObjectContext
}
(2) Alternatively, whenever a view opens another view, it just sets the next view's managedObjectContext property to it's own. So that every view opens with a context. This is useful if you actually have multiple data objects for some reason.
If your just using an array or a custom data model class just substitute its name for the managedObjectContext in the code above.
Check out this question. I recommend using a singleton class and creating some listener pattern to signal when the data has changed (or just reload, always, before your view becomes visible).
You might want to store your feed items in memory by using the a singleton
Something similar to what is being used: Singleton shared data source in Objective-C

Resources