I am trying to use a UISearchBar
to query multiple properties of a NSManagedObject
I have a NSManagedObject
called Person
, every person has a name
and socialSecurity
property. Right now my code can perform a search (fetch) for one of those properties or the other, but not both at the same time.
- (void) performFetch
{
[NSFetchedResultsController deleteCacheWithName:@"Master"];
// Init a fetch request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"MainObject" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Apply an ascending sort for the color items
//NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Term" ascending:YES selector:nil];
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"fullName" ascending:YES selector:@selector(caseInsensitiveCompare:)];
NSArray *descriptors = [NSArray arrayWithObject:sortDescriptor];
[fetchRequest setSortDescriptors:descriptors];
// Recover query
NSString *query = self.searchDisplayController.searchBar.text;
//if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"Term contains[cd] %@", query];
if(searchValue==1)
{
if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name contains[cd] %@", query];
}
else {
if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"socialSecurity contains[cd] %@", query];
}
// Init the fetched results controller
NSError *error;
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"pLLetter" cacheName:nil];
self.fetchedResultsController.delegate = self;
if (![[self fetchedResultsController] performFetch:&error]) NSLog(@"Error: %@", [error localizedDescription]);
[self.tableView reloadData];
}
I don't know how to put both properties into this statement...
if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name contains[cd] %@", query];
Any help or ideas would be greatly appreciated.
You could use a NSCompoundPredicate
.
Like this:
NSPredicate *predicateName = [NSPredicate predicateWithFormat:@"name contains[cd] %@", query];
NSPredicate *predicateSSID = [NSPredicate predicateWithFormat:@"socialSecurity contains[cd] %@", query];
NSArray *subPredicates = [NSArray arrayWithObjects:predicateName, predicateSSID, nil];
NSPredicate *orPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates];
request.predicate = orPredicate;
there is a NSCompoundPredicate
for AND
too: andPredicateWithSubpredicates:
You can append multiple search terms in an NSPredicate
using the usual boolean operands such as AND/OR.
Something like this should do the trick.
[NSPredicate predicateWithFormat:@"name contains[cd] %@ OR ssid contains[cd] %@", query, query];
Hope that helps :)
Addition to @Matthias's answer, you can also use NSCompoundPredicate for your AND operations like this.
Obj-C - AND
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"X == 1"];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"X == 2"];
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[predicate1, predicate2]];
Swift - AND
let predicate1:NSPredicate = NSPredicate(format: "X == 1")
let predicate2:NSPredicate = NSPredicate(format: "Y == 2")
let predicate:NSPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1,predicate2] )
Swift 3 - AND
let predicate1 = NSPredicate(format: "X == 1")
let predicate2 = NSPredicate(format: "Y == 2")
let predicateCompound = NSCompoundPredicate(type: .and, subpredicates: [predicate1,predicate2])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With