NSFetchedResultsController with search NSFetchedResultsController with search objective-c objective-c

NSFetchedResultsController with search


How is Guy's answer code any different from the question? As far as I can guess, the filterContentForSearchText:scope method is called by the shouldReload methods?

Anyway, here's some similar code that I added in the CoreDataBooks sample to include search. Add a Search Display Controller in IB for the CoreDataBooks example. Then I added code to RootViewController.m as follows:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { NSInteger searchOption = controller.searchBar.selectedScopeButtonIndex; return [self searchDisplayController:controller shouldReloadTableForSearchString:searchString searchScope:searchOption];}- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption { NSString* searchString = controller.searchBar.text; return [self searchDisplayController:controller shouldReloadTableForSearchString:searchString searchScope:searchOption];}- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString*)searchString searchScope:(NSInteger)searchOption { NSPredicate *predicate = nil; if ([searchString length])  if (searchOption == 0) // full text, in my implementation.  Other scope button titles are "Author", "Title"   predicate = [NSPredicate predicateWithFormat:@"title contains[cd] %@ OR author contains[cd] %@", searchString, searchString];  else   // docs say keys are case insensitive, but apparently not so.   predicate = [NSPredicate predicateWithFormat:@"%K contains[cd] %@", [[controller.searchBar.scopeButtonTitles objectAtIndex:searchOption] lowercaseString], searchString]; [fetchedResultsController.fetchRequest setPredicate:predicate];    NSError *error = nil;    if (![[self fetchedResultsController] performFetch:&error]) {  NSLog(@"Unresolved error %@, %@", error, [error userInfo]);  abort();    }            return YES;}

PS. To answer Vivas, using a UISearchDisplayController it creates a new table view automatically for overlaying the filtered list. You can check which tableView is being used as shown in the docs, but in the simplest setup it just works because the fetchedResultsController is either showing a filtered version in the search's table view or showing all data in your table view.


Appearantly this is a better way:

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope{    self.savedSearchTerm = searchText;    freshData = NO;    if (searchText !=nil)    {            NSPredicate *predicate =[NSPredicate predicateWithFormat:@"name contains[cd] %@", searchText];            [fetchedResultsController.fetchRequest setPredicate:predicate];    }    else    {            NSPredicate *predicate =[NSPredicate predicateWithFormat:@"All"];            [fetchedResultsController.fetchRequest setPredicate:predicate];    }    NSError *error = nil;    if (![[self fetchedResultsController] performFetch:&error]) {            // Handle error            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);            exit(-1);  // Fail    }               [self.tableView reloadData];    //    [searchBar resignFirstResponder];       //    [_shadeView setAlpha:0.0f]; }