Albert Mata
iOS Developer

Personal Notes On Core Data Tutorial For iOS

My personal notes on this article are licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License
The original document in which this notes are based is copyrighted by Apple Inc.
Published: December 30th, 2011

Some months ago I read Apple's Core Data Tutorial for iOS as my first approach to this technology. While doing that I thought it would be a good idea to take some personal notes to help myself make my ideas clear. But maybe these notes can be useful for anyone else, so here they are.

Some initial notions

The Core Data model is the .xcdatamodeld file and is usually called the managed object model. When creating a Core Data project we have these three properties (what's called the Core Data stack):

@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;

And these two instance methods as well:

- (NSURL *) applicationDocumentsDirectory;
- (void) saveContext;

Some basic definitions

Let's make these concepts clear:

Every managed object has a reference to the entity of which it is an instance. Although in principle we can represent an entity using NSManagedObject, in practice it's common to use a custom class as this yields several benefits (compile-time checking, code completion, etc). When we have the entity created, we create the custom class to represent it with File > New File > Managed Object Class. This class won't have a dealloc method, as long as Core Data is responsible for the life-cycle of all modeled properties of a managed object (but if we add our own instance variables that do not have corresponding properties in the managed object model, then we need to manage those ourselves as normal with a dealloc method). After doing this, the entity will be automatically updated and won't show NSManagedObject anymore but our new custom class.

Creating managed objects

We typically create a managed object using a convenience method insertNewObjectForEntityForName:inManagedObjectContext:. After creating it, we can set its property values. This newly created object is of type NSEntityDescription so we need to cast it to our custom class. It's important to take into account that changes to the object are not pushed to the persistent store until we explicitly save the context. We save it this way:

NSError *error = nil;
if (![managedObjectContext save:&error]) {
    // handle the error
}

If some error happens it's our entire responsibility to decide what to do.

We get and set a managed object's property values using accessor methods, just as we would any other object. We can also use key-value coding, just as we would any other object as well, but using accessor methods is much more efficient.

Fetching managed objects

To fetch objects from a persistent store, we need a managed object context and a fetch request (an instance of NSFetchRequest). This fetch request specifies, as a minimum, the entity we're interested in (an instance of NSEntityDescription that we get using its convenience method entityForName:inManagedObjectContext:). But usually we also specify some order (an array of NSSortOrdering objects) and conditions (instances of NSPredicate).

After we've created and customized the NSFetchRequest we get the records into an NSArray (usually an NSMutableArray if we want to insert or delete objects):

NSError *error = nil;
NSMutableArray *mutableFetchResults =
               [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
    // handle the error
}      

Deleting managed objects

It's basically a two steps process. We first use the NSManagedObjectContext's method deleteObject: to mark an object as deleted. And after that we commit the action using save:.