views:

21

answers:

1

Hi,

Let say the data entities are: Bookshop <--->> Books

How do I fetch all books belonging to a specific book shop that contain "cloud" in the name for example? The following method feel clunky.

Bookshop *bookshop = (Bookshop *) nsManagedObjectFromOwner;
NSString *searchTerm = @"cloud";

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Books" 
                          inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:
              @"ANY bookshop.Name == '%@' && Name contain[cd] '%@'", 
              bookshop.Name, searchTerm];
[fetchRequest setPredicate: predicate];

How could I improve this code to handle if there are 2 book shops with very similar names? And maybe also performance improvement for fetching as the UITableView should update as the user type in book name.

+1  A: 

This might be a matter of personal taste, but I like to define and use fetch request templates. Then you can do something like this:

Bookshop *bookshop = (Bookshop *) nsManagedObjectFromOwner;
NSString *searchTerm = @"cloud";

NSDictionary *substitutionDictionary = [NSDictionary dictionaryWithObjectsAndKeys:bookshop.Name, @"BOOKSHOP_NAME", searchTerm, @"BOOK_NAME", nil];
// BOOKSHOP_NAME and BOOK_NAME are the name of the variables in your fetch request template

NSFetchRequest *fetchRequest = [model fetchRequestFromTemplateWithName:@"YourFetchRequestTemplateName" substitutionVariables:substitutionDictionary];

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Books" 
                      inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

It isn't less code, but it is less clunky because all of your fetch requests are defined in one place. Or maybe I'm misunderstanding your question?

As far as the second part of your question is concerned, I haven't actually used this myself, but the NSFetchedResultsControllerDelegate provides the methods you need to automatically keep your table of results up-to-date. Try -controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:. Obviously it implies using an NSFetchedResultsController.

JoBu1324