views:

108

answers:

2

I'm using CoreData in my lastest iPhone app. I find it complex at the beginning but I guess this is the best choice when you need to store objects in an iPhone app (http://inessential.com/2010/02/26/on_switching_away_from_core_data).

Is there any best practices when using CoreData in an iPhone app ? For example, I don't want all my controllers to deal with this NSManagedObjectContext that you need when you want to make requests. Do you define a class just for CoreData requests ?

A: 

Thanks Brad for pointing to this question.

As mentionned on Apple documentation [1], the context have to be passed to each new view controller that need CoreData.

On iPhone:

By convention, you can often get a context from a view controller. It’s up to you, though, to follow this pattern. When you implement a view controller that integrates with Core Data, you can add an NSManagedObjectContext property.

A view controller typically shouldn’t retrieve the context from a global object such as the application delegate. This tends to make the application architecture rigid. Neither should a view controller typically create a context for its own use. This may mean that operations performed using the controller’s context aren’t registered with other contexts, so different view controllers will have different perspectives on the data.

When you create a view controller, you pass it a context. You pass an existing context, or (in a situation where you want the new controller to manage a discrete set of edits) a new context that you create for it. It’s typically the responsibility of the application delegate to create a context to pass to the first view controller that’s displayed.

[1] - http://developer.apple.com/iphone/library/documentation/DataManagement/Conceptual/CoreDataSnippets/Articles/stack.html#//apple_ref/doc/uid/TP40008283

Pierre Valade
+1  A: 

I usually create a dedicated object to manage my Core Data stack and related objects and behaviors. This is useful because there is a lot of boiler plate with Core Data so I can make a generic base manager class and then use a subclass for each app. I usually call it AppNameDataModel.

I prefer to hide the managed object context inside the DataModel object. This forces the other objects in the app to ask the DataModel object for access to the Core Data stack which gives good encapsulation and safety.

Usually, I create methods in the DataModel class to return fetches for entities e.g.

-(NSFetchRequest *) entityNameFetch;

... and then have a performFetch method in the DataModel. In use, a controller ask for a fetch for an entity, configures the fetch and then ask the DataModel to perform the fetch and return the results. You can script the generation of the methods that return the fetch and the perform fetch is boiler plate as well. This all saves a lot of time especially when prototyping.

A reference to DataModel instance itself can be passed from controller to controller but I think this is a valid use of the singleton pattern so I often make the DataModel a singleton and the provide a category on UIViewController for a property to access it. That means that any view controller I add to the project automatically has access to the DataModel.

This pattern keeps everything nicely encapsulated and modular. It makes it easy to add new views or to share the data model between projects. It takes a little work to set up initially but once you have the base class, future use is massively sped up.

TechZen