NSPredicate: Combine CONTAINS with IN

netshark1000 picture netshark1000 · Nov 20, 2012 · Viewed 15.3k times · Source

I have a set of users in CoreData and an search field in my application. User has the properties firstname and name.

Currently I have a predicate like "user.name CONTAINS[c] %@ OR user.firstname CONTAINS[c] %@ "

This works until the user types a full name like "john smith". Even if he types "john sm" the John Smith-Object should be found.

What is the predicate to combine an array (IN) of search terms with CONTAINS?

Answer

Martin R picture Martin R · Nov 20, 2012

I don't think that you can combine "IN" with "CONTAINS" in a predicate. But you could split the search string into words, and create a "compound predicate":

NSString *searchString = @"John  Sm ";
NSArray *words = [searchString componentsSeparatedByString:@" "];
NSMutableArray *predicateList = [NSMutableArray array];
for (NSString *word in words) {
    if ([word length] > 0) {
        NSPredicate *pred = [NSPredicate predicateWithFormat:@"user.name CONTAINS[c] %@ OR user.firstname CONTAINS[c] %@", word, word];
        [predicateList addObject:pred];
    }
}
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicateList];
NSLog(@"%@", predicate);

This example produces the predicate

(user.name CONTAINS[c] "John" OR user.firstname CONTAINS[c] "John") AND
(user.name CONTAINS[c] "Sm" OR user.firstname CONTAINS[c] "Sm")

which would match "John Smith", but not "John Miller".