Core Data on iOS 5 Tutorial: How To Work with Relations and Predicates

This is a tutorial where you’ll learn how to work with predicates and relationships in Core Data. It is written by iOS Tutorial Team member Cesare Rocchi, a UX designer and developer specializing in web and mobile applications. Good news – by popular request, we now have a 4th part to our Core Data tutorial […] By Cesare Rocchi.

Leave a rating/review
Save for later
Share
You are currently viewing page 6 of 6 of this article. Click here to view the first page.

More Fun with Predicates

If you want to search for a name that matches the search term exactly, then modify the predicate creation line as follows:

NSPredicate *pred = [NSPredicate predicateWithFormat:@"name == %@", self.searchBar.text];

Want to try something a bit more complicated? Remember that your data objects aren’t alone: they have relationships. You can define a predicate referring to a value accessed via a relationship. For example, the following looks for zip codes ending with whatever the user types into the search box.

NSPredicate *pred = [NSPredicate predicateWithFormat: @"details.zip ENDSWITH %@", self.searchBar.text]; 

Note that you can access relationships using dot notation – much like Objective-C properties. In this example, you’re checking the zip property of the bank details.

Not complicated enough? How about checking for banks closed after a given date? Maybe you want to see how many have closed since the beginning of the year.

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
NSDate *date = [dateFormatter dateFromString:self.searchBar.text];                        
NSPredicate *pred = [NSPredicate predicateWithFormat: @"details.closeDate > %@", date];

Here you build a date from the input string, and use the > operator.

You can even exploit a “chain” of objects going down to the tag level. For example, if you want to retrieve banks that have more than one tag, you can use the @count operator, which works on properties modeled as a set.

NSPredicate *pred = [NSPredicate predicateWithFormat: @"details.tags.@count > 0"];

As mentioned before, you can use AND/OR logical operators to combine filter criteria. Let’s assume the user will provide two values split by a colon (:). For example, to look for a bank by name and city, he types in “bank:testville”. That can be handled as follows:

    NSArray *queryArray;
    if ([self.searchBar.text rangeOfString:@":"].location != NSNotFound) {
        queryArray = [self.searchBar.text componentsSeparatedByString:@":"];
    }
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"(name CONTAINS[c] %@) AND (city CONTAINS[c] %@)", 
        [queryArray objectAtIndex:0], [queryArray objectAtIndex:1]];

First you create an array with the two values by splitting the search string into two. Then you build a predicate using the two separate values and the AND logical operator. The above predicate can be translated as: “look for the banks whose names contain the string x and whose city names contain the string y.”

The final source code archive for this tutorial contains a put a constant called SEARCH_TYPE, which ranges from 1 to 11 and allows you to experiment with different operators for predicates. Check it out in the download link below!

Where To Go From Here?

Here is a sample project with all of the code from this tutorial so far.

I hope you’re feeling more like a wizard when it comes to relations and predicates.

Want to experiment some more? Instead of “chaining” predicates in a string, you might want to explore the convenient classes NSCompoundPredicate and NSComparisonPredicate. These allow you to achieve the same results in code.

If you have any questions or comments about this tutorial or relationships/predicates in general, please join the forum discussion below!


This is a post by iOS Tutorial Team member Cesare Rocchi, a UX designer and developer specializing in web and mobile applications. You can also find me on

Contributors

Over 300 content creators. Join our team.