Very strange results using NSPredicate combined with a search box on a tableview and NSFetchedResultsController
It’s supposed to be filtering based on matching name… however, if I type in any valid name, I get a few results that are just not correct. If I type in any full name like “Mike Johnson” or “Kelly Michaels” I always get the same filtered result of “Angelo Smith”.
The NSLog will show
“name CONTAINS[cd] \”Kelly Michaels\””
Yet the filtered result displaying on screen will only show Angelo Smith? Any ideas how to troubleshoot this?
I’ve been using the solution in this stack post if you need more details of what I’m doing
How to filter NSFetchedResultsController (CoreData) with UISearchDisplayController/UISearchBar
- (NSFetchedResultsController *)newFetchedResultsControllerWithSearch:(NSString *)searchString
{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
NSPredicate *filterPredicate = nil;
/*
Set up the fetched results controller.
*/
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Staff" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSMutableArray *predicateArray = [NSMutableArray array];
if(searchString.length)
{
NSLog(@"here searchString is %@", searchString);
// your search predicate(s) are added to this array
[predicateArray addObject:[NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@", searchString]];
// finally add the filter predicate for this view
NSLog(@"%@", predicateArray);
if(filterPredicate)
{
filterPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:filterPredicate, [NSCompoundPredicate orPredicateWithSubpredicates:predicateArray], nil]];
}
else
{
filterPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:predicateArray];
}
}
[fetchRequest setPredicate:filterPredicate];
...
I wouldn’t create a new FRC when filtering unless the dataset is changing. Instead just change the predicate and do another fetch (in a custom method called something like filterContentForSearchText)
Example: