2

I have a Contact : NSManagedObject. I want to search all contacts by name (full name). The search should perform like that of iPhone's Contacts app. So, name matches searchString if every word in searchString begins with any word in name. The search is case & diacritic insensitive.

E.g., name "Matt Di Pasquale" matches searchString "Matt Pa", "Matt Mat", and "Pasq Di má" but does not match "att" or "squale".

ma11hew28
  • 121,420
  • 116
  • 450
  • 651

1 Answers1

1

UPDATE: Watch the WWDC 2010 Session Video: Optimizing Core Data Performance on iPhone OS for a much faster way to do this.

Based on another answer about NSPredicate, create an NSCompoundPredicate from subpredicates using an ICU regular expression:

NSArray *searchWords = [searchString words]; // see link below (1)
NSMutableArray *subpredicates = [NSMutableArray arrayWithCapacity:[searchWords count]];
for (NSString *searchWord in searchWords) {
    [subpredicates addObject:[NSPredicate predicateWithFormat:
                              @"name CONTAINS[cd] %@ AND" // maybe speeds it up
                              " name MATCHES[cd] %@",
                              searchWord, [NSString stringWithFormat:
                                           @".*\\b%@.*", searchWord]]];
}
fetchRequest.predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];

I think MATCHES filtering happens after the objects have been fetched into memory, so name CONTAINS[cd] %@ should limit the number of fetched objects and perhaps speed things up.

(1) Cocoa Plant implements -[NSString words]

Community
  • 1
  • 1
ma11hew28
  • 121,420
  • 116
  • 450
  • 651