So, now you've got your files set up for Core Data (see part 1) and you've built a model (see part 2). How do you actually start using the thing? This article will cover the basics of what you'd know in SQL as SELECT; in other words, it tells you how to retrieve your data.
Selecting Data
In order to select data from your persistent store you need two things. First, you need a managedObjectContext. This should have been created for you by default when you setup your project to use Core Data (see part 1). You will use it as an argument and send it messages. Second, you'll need at least one class of managed objects to work with.
Once you've done these things, you can access the managed objects in your persistent store as follows:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Card"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];NSError *error;
NSArray *items = [self.managedObjectContext
executeFetchRequest:fetchRequest error:&error];[fetchRequest release];
This structure of commands will be identical any time you do a simple select. First, you create an NSFetchRequest. Second, you define what class you want to select from by creating an NSEntityDescription (using your managedObjectContext variable). Third, you give that entity description to NSFetchRequest. Fourth, you tell your managedObjectContent to executeFetchRequest:error: in order to actually retrieve your data; it'll place the results in an NSArray. Fifth, you cleanup.
This particular request will retrieve all items of the type Card. If you want to do something fancier, like only requesting certain instances of Card or sorting your results, then you'll need to do more work ...
Setting a Predicate
In order to select only some of a managed object, you need to define an NSPredicate object, then set it. Here's an example of selecting a Card with a very specific id:
NSPredicate *predicate = [NSPredicate
predicateWithFormat:@"id=%i",id];
[fetchRequest setPredicate:predicate];
These commands are given as part of the typical NSFetchRequest sequence, after you've created the NSFetchRequest object and before you've executed it.
The NSPredicate class documentation shows the possible language you can use. Generally, you can compare with =, >, < or LIKE. There's also some more complex work you can do with arrays and ways that you can form ANDs or ORs (by using NSCompoundPredicate).
The substitution variables should only be used to substitute the values you're matching. If you instead want to substitute for a key value (e.g., 'id' in the above example), you can use %K. You should also be aware that you can use %@ to substitute an object.
The following shows an object substitution:
NSPredicate *predicate = [NSPredicate
predicateWithFormat:@"location=%@",thisDeck];
[fetchRequest setPredicate:predicate];
If you look at the data model in part 2 of this series, you'll see that 'location' is actually a relationship from the Card class to the CardStack class. This example thus shows that you can search on a relationship just as easily as you can search on a attribute.
Sorting Your Data
There's one final property that you should be aware of because it's used pretty frequently when fetching Core Data: sortDescriptors. This is an NSArray of NSSortDescriptors, which explain, in order of decreasing importance, how to sort the data you're retrieving.
The following example not only shows how to set the sortDescriptors property, but also shows it in the context of a complete NSFetchRequest, including entity definition and an NSPredicate.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Card"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];NSPredicate *predicate = [NSPredicate
predicateWithFormat:@"location=%@",thisDeck];
[fetchRequest setPredicate:predicate];NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:@"deckOrdering" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[sort release];NSError *error;
NSArray *items = [self.managedObjectContext
executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];
Note that sortDescriptors expects an array. Thus, if you are just sorting by one variable you have to create your NSSortDescriptor and then make that descriptor into the complete contents of an array, as is shown here.
Accessing Your Data
So, you've retrieved your Core Data. How do you manipulate it? First up, remember that the Core Data methods always return an NSArray. You'll usually need to access individual objects within that array. Here's an example of an individual Card being pulled from an array (then sent to the cardDraw:atHeight: method):
CArdLayer *newLayer = [self drawCard:[cardList objectAtIndex:i] atHeight:100];
It's very easy to access the parts of a data object because every attribute and relationship in your data model is set as a property in the data object you're retrieving. Many of them are encoded as either NSStrings or NSNumbers. Here's an example of retrieving the 'id' attribute from a Card:
theCardLayer.tag = [[theCard id] intValue];
Things only get somewhat more complex when you're retrieving a one-to-many relationship. In this case, rather than retrieving the data type, you're retrieving an NSSet (even if there's only one of the type of object connected up). Here's an example of how to retrieve an image for a card, where there's a one-to-many relationship between Card and CardPics:
CardPics *cardInfo = [[theCard images] anyObject];
(There are, of course, more comprehensive methods for retrieving data from NSSets which you can find in the appropriate class documentation.)
That's all there is to it! However, the retrieval of data is one of the elements of Core Data that offers the most variability. If you need more information, you should probably start with the NSPredicate class documentation (and the related Predicate Programming Guide).
Next Up: Storing & Changing Data.

Thanks for these articles. Out of all the material I have read on core data yours by far have been the most helpful. I'm eagerly awaiting the next article on Storing and Changing Data. When is that going to be posted?
Posted by: Chris | September 07, 2009 at 06:59 PM
Glad it's been useful! Part 4 will be posted sometime this week, then I expect to have Part 5 up next Tuesday, and that's as far as I've planned at the moment.
Posted by: Shannon Appelcline | September 07, 2009 at 07:05 PM
thanks for the series.
the things i don't understand from part 3:
- in the line NSPredicate "*predicate = [NSPredicate predicateWithFormat:@"location=%@",thisDeck];" where does 'thisDeck' come from? when/where/how is it set?
Posted by: jj | September 22, 2009 at 05:38 PM
It's an arbitrary variable that came in from outside the function. Somewhere, something else in the program, thus, got a handle for a "CardStack" object ... probably from a "select" or by looking up a property.
Posted by: Shannon Appelcline | September 23, 2009 at 03:20 PM
Thanks so much for the articles. They are a great help. One question, I'm trying to access a to-many relationship, say recipes to ingredients where there is a Recipe entity with a to-many relationship to an Ingredient entity.
If I want to pull all the recipes from an ingredient, it seems like i could have something like:
NSArray *recipeIngredients = [recipe.ingredients allObjects];
but I just can't seem to get this right. Can anyone explain this relationship retrieval a little more clearly?
Posted by: Jeff | December 31, 2009 at 10:36 AM
I thank you greatly for your tutorials and I have purchased your book and find it very informative and helpful.
What I am trying to do is write an App that is a two level drill-down with a detailView that can display Address, Description and an image for each selected item using Core Data.
I have been able to create one that can do all of that except the image part. It draws its data from an xml file. I have pieced it together from other tutorials.
I cannot, however, work out how to have images stored in the App and Displayed. I wish the App to have no user editing facility so the separate images need to be loaded in from the start.
I have gone over and over your recipes App but cannot figure out how to do this.
If you could possibly write a tutorial on how to do this I would be greatly appreciative.
Cheers
Posted by: Almeist | January 28, 2010 at 03:10 AM
> SELECT; in other words, it tells you have to retrieve your data.
You *HAVE TO* retrieve your data?
Huh?
Posted by: Susan | March 11, 2010 at 07:52 AM
And that's why editors would be good for blogs. It should be "how to retrieve data".
Posted by: Shannon Appelcline | March 11, 2010 at 10:31 AM