Core Data stores are designed to work efficiently with NSPredicates.
Predicates allow you to create fetch requests that select only those
managed objects that match the predicate’s rule or rules. Adding a
predicate to a fetch request limits the fetched results to matching
objects.
This recipe uses a search bar to
select data from the persistent store, displaying the results in a
table’s search sheet. Figure 19-2 shows a search in progress.
As the text in the search bar at the top of the table changes, the search bar’s delegate receives a searchBar:textDidChange: callback. In turn, that method performs a new fetch.
The recipe’s performFetch method creates that simple predicate based on the text in the search bar. It sets the request’s predicate property to limit matches to names that contain the text, using a case insensitive match. contains matches text anywhere in a string. The [cd] after contains
refers to case and diacritic insensitive matching. Diacritics are small
marks that accompany a letter, such as the dots of an umlaut or the
tilde above a Spanish n.
For more complex queries,
assign a compound predicate. Compound predicates allow you to combine
simple predicates together using standard logical operations like AND,
OR, and NOT. Use the NSCompoundPredicate
class to build a compound predicate out of a series of component
predicates, or include the AND, OR, and NOT notation directly in NSPredicate text.
All the cell and section methods are tied to the results object and its properties, simplifying implementation even when adding these search table features.
Recipe 1. Using Fetch Requests with Predicates
- (void) performFetch
{
// Init a fetch request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Crayon" inManagedObjectContext:self.context];
[fetchRequest setEntity:entity];
// Apply an ascending sort for the color items
NSSortDescriptor *sortDescriptor =
[[NSSortDescriptor alloc] initWithKey:@"name"
ascending:YES selector:nil];
NSArray *descriptors = [NSArray arrayWithObject:sortDescriptor];
[fetchRequest setSortDescriptors:descriptors];
// Recover query
NSString *query = self.searchBar.text;
if (query && query.length) fetchRequest.predicate =
[NSPredicate predicateWithFormat:@"name contains[cd] %@",
query];
// Init the fetched results controller
NSError *error;
self.fetchedResultsController =
[[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:self.context
sectionNameKeyPath:@"section" cacheName:@"Root"];
self.fetchedResultsController.delegate = self;
[self.fetchedResultsController release];
if (![[self fetchedResultsController] performFetch:&error])
NSLog(@"Error %@", [error localizedDescription]);
[fetchRequest release];
[sortDescriptor release];
}
|