views:

1743

answers:

4

What is the best practice to filter the NSFetchedResultsController data? do i need to re-initialize it every time the searchbar's text changes?

I am using a UISearchDisplayControllers and i'm implementing: - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString;

Thx.

+3  A: 

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];

 }
Guy
exit(-1) is a bit harsh.
0xced
A: 

Hi Guy,

How did you end up handling the table view data source methods so that the table view will Know whether to display the 'filtered list' or not?

Vivas
A: 

Hi Guy,

Thanks for posting this code. I am really having a hard time trying out to figure how to let the tableview source whether to display the 'filtered list' or not?

I will really appreciate your help or tips to implement this.

Thanks in advance,

Sserye
+3  A: 

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]);
  exit(-1);
    }           

 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.

dk