Fetching Events

The goal of this chapter is to fetch existing Event objects when the application launches.

Fetching Managed Objects

To fetch objects from a persistent store, you need a managed object context and a fetch request. A fetch request is an instance of NSFetchRequest. As a minimum, it specifies the entity you’re interested in. It may also specify any constraints on the values that the objects should have and what order you want them back in. For example, in a corporate information application, you might create a fetch request to retrieve Employee objects, ordered by name, whose salary is greater than a certain amount. The constraints are represented by a predicate—an instance of NSPredicate. (For more about predicates see Predicate Programming Guide.) The sort order is represented by an array of NSSortOrdering objects.

image: ../Art/fetch_flow_of_data.jpg

Unless you really need all the objects of a particular entity, you should use a predicate to limit the number of objects returned to those you’re actually interested in. (If you’re displaying objects in a table view, you can also use a fetched results controller—NSFetchedResultsController—to manage a result set for you. It works hard to ensure that as little data as possible is held in memory.)

Note that you don’t always need to execute a fetch to retrieve objects. Core Data, if necessary, automatically retrieves objects that are at the destination of a relationship. For example, if you execute a fetch to retrieve an Employee object, then ask it for its related Department, then Core Data fetches the Department for you if it hadn’t already been fetched.

Creating and Executing the Request

When the table view controller loads its view, it should fetch the Event objects and keep them in the events array so that they can be displayed later. The events array needs to be mutable since the user can add and remove events.

Create the Request

Create a fetch request and set the entity.

>> Add the following code at the end of the current implementation of viewDidLoad:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];

The method of interest here is NSEntityDescription’s entityForName:inManagedObjectContext:. You provide the name of the entity you want and the managed object context you’re dealing with; the method then asks for the (managed object) context’s (persistent store) coordinator’s (managed object) model and retrieves from that the entity with the name you specified (you can refer back to “The Core Data Stack” to see a pictorial representation). Conceptually it’s not very difficult (you just navigate down the stack), and you could do it yourself easily enough, but it’s much more convenient to use the class method.

Set the Sort Descriptor

If you don’t specify a sort descriptor, the order in which objects are returned from a fetch is undefined. To retrieve the Events in chronological order, you therefore need to specify a sort descriptor for the fetch. Because you might want to specify multiple sort orderings (for example, you might want to sort employees by department, last name, and first name), you need to put the sort descriptor in an array.

>> At the end of the current implementation of viewDidLoad, create a sort descriptor to order Event objects by creation date—most recent first—and a mutable array. Add the sort descriptor to the array, and set the array as the fetch request’s sortDescriptors array:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];

(It’s often useful to use the initWithObjects: method of NSArray in case you want to add more sort descriptors later.)

Execute the Request

Having created a fetch request, you now execute it. The events array needs to be mutable, so make a mutable copy of the result.

>> Add the following code at the end of the current implementation of viewDidLoad:

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

As previously, this example leaves it up to you to decide how to handle any error (see “Handling Errors”).

Finish Up

The final steps are to set the view controller’s events array instance variable and to release objects that were allocated.

>> Add the following code at the end of the current implementation of viewDidLoad:

[self setEventsArray:mutableFetchResults];
[mutableFetchResults release];
[request release];

Build and Test

If you build and run the application, you should find that it compiles correctly and that existing Event objects are displayed when the application launches.

Core Data Recap

The important points from this chapter are that:


Did this document help you? Yes It's good, but... Not helpful...