Implementing a SearchBar inside my TableView and using NSFetchedResultsController and the appropriate predicate to get searches working

StackOverflow https://stackoverflow.com/questions/19583185

Question

I have a simple TableViewController which has an add button which goes over to a ModalViewController; the user adds in text into a text field, presses save and that dismisses and the entry is added to the Entities and Attributes in Core Data and displayed in the TableViewController. It works well.

I firstly started off with another button that pulled up a UISearchBar in a Table View and I could search for results and pull that back; that worked. I then added a new tab to the bottom of the TableViewController and managed to get the search bar and table in there.

Now, I want the SearchBar at the top of the Single Table View and I want the user to be able to type and for it to dynamically search the TableView.

My fetchRequest looks like this currently for the TableView (without the searching bar):

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

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"occasion.dateOfEvent" ascending:NO selector:@selector(localizedCaseInsensitiveCompare:)];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
    [fetchRequest setFetchBatchSize:20];
    //NSPredicate *pred = [NSPredicate predicateWithFormat:@"ANY whoBy.name CONTAINS[c] %@", self.searchBar.text];
    //[fetchRequest setPredicate:pred];
    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"occasion.dateOfEvent" cacheName:nil];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;
    return _fetchedResultsController;

I'm searching across the Transaction, etc. Now, the only difference between this code and my other view controller which has the search bar is the fact that the NSPredicate is uncommented. The searching works well. If I uncomment that in this code, when I run it, I get the following error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid predicate: nil RHS'
*** First throw call stack:

I understand what's happening because I want the TableViewController to display WITHOUT a predicate, but when I search, I went that predicate to go in effect. Any help on how to go about getting this working would be massively appreciated!

My search bar delegate method looks like this:

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    NSError *error;
    if (![[self fetchedResultsController] performFetch:&error])
    {
        NSLog(@"Error in search %@, %@", error, [error userInfo]);
    } else
    {
        [self.tView reloadData];
        [self.searchBar resignFirstResponder];
        [noResultsLabel setHidden:_fetchedResultsController.fetchedObjects.count > 0];
    }
}
Was it helpful?

Solution

You should set a predicate only if a search string is given:

if ([self.searchBar.text length] > 0) {
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"ANY whoBy.name CONTAINS[c] %@", self.searchBar.text];
    [fetchRequest setPredicate:pred];
}

If the search string is empty, no predicate is set and therefore all results are returned.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top