How to retrieve a Managed Object in Core Data Fetch Requests

- by

Retrieving Managed Objects is somewhat more complex than creating them, mainly because you can filter what you’re getting back rather than retrieve everything that your store file has to offer.

Let’s first illustrate a basic NSFetchRequest. For the following examples I’m using the iOS Master/Detail template which provides an Entity called Event with a property called timeStamp. I’ve created custom subclasses for this entity. Press the add button a few times so we have some data, then quit the application.

Basic Fetch Request

Here’s how we can retrieve all our values using a basic Fetch Request:

    // create a fetch request
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // fetch all objects
    NSError *error = nil;
    NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        NSLog(@"Houston, we have a problem: %@", error);
    }

    // display all objects
    for (Event *event in fetchedObjects) {
        NSLog(@"%@", [event.timeStamp description]);
    }

The easiest way to get this code is by using a code snippet from the Xcode library (search for fetch, the first one is a “basic fetch”).

Note that the results are unfiltered, which means they’re not necessarily in the order you would like them to be in. To remedy this, you can use a Sort Descriptor:

Fetch Request with Sort Descriptors

    // create a fetch request
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // define a sort descriptor
    NSSortDescriptor *descriptor = [[NSSortDescriptor alloc]initWithKey:@"timeStamp" ascending:YES];
    NSArray *scArray = [[NSArray alloc]initWithObjects:descriptor, nil];

    // give sort descriptor array to the fetch request
    fetchRequest.sortDescriptors = scArray;

    // fetch all objects
    NSError *error = nil;
    NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        NSLog(@"Houston, we have a problem: %@", error);
    }

    // display all objects
    for (Event *event in fetchedObjects) {
        NSLog(@"%@", [event.timeStamp description]);
    }

You can pass more than one Sort Descriptor, hence we need to pass an NSArray to the fetch request. A usage example would be “list all employers alphabetically, in order of which they’ve started working”. To do this, create another sort descriptor, then add both to the array.

The easiest way to get this is to use the Xcode Code Snippets again, this time select the “fetch with sorting” and it will have all this code ready for you.

Fetch Request using a Predicate

Predicates are filters with which you can specify conditions, such as “is this date older than x”, “does the first name contain steve”, and so forth. I have written a more in-depth article on Predictates elsewhere on this site and won’t go into the details.

Here’s how you create a Fetch Request with a Predicate, combined with a Sort Descriptor:

    // create a fetch request
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
    
    // setup a predicate
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"timeStamp > %@", [NSDate date]];
    
    // give the predicate to the fetch request
    fetchRequest.predicate = predicate;
    
    // define a sort descriptor
    NSSortDescriptor *descriptor = [[NSSortDescriptor alloc]initWithKey:@"timeStamp" ascending:YES];
    NSArray *scArray = [[NSArray alloc]initWithObjects:descriptor, nil];
    
    // give sort descriptor array to the fetch request
    fetchRequest.sortDescriptors = scArray;
    
    // fetch all objects
    NSError *error = nil;
    NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        NSLog(@"Houston, we have a problem: %@", error);
    }
    
    // display all objects
    for (Event *event in fetchedObjects) {
        NSLog(@"%@", [event.timeStamp description]);
    }

 

If you don’t need the Sort Descriptor, just remove that code from the example. This snippet is also available from Xcode and is called “fetch with predicate”.

For more information on Predicates, check out Apple’s Predicate Programming Guide.



If you enjoy my content, please consider supporting me on Ko-fi. In return you can browse this whole site without any pesky ads! More details here.

Leave a Comment!

This site uses Akismet to reduce spam. Learn how your comment data is processed.