58

I'm looking for a way to use NSPredicate to set a LIKE condition to fetch objects. In addition to that, an OR would be useful as well. I'm trying to do something where if a user searches "James" I can write an NSPredicate that will do the equivalent of:

select * from users where firstname LIKE '%James%' OR lastname LIKE '%James%';
Peter DeWeese
  • 18,141
  • 8
  • 79
  • 101
randombits
  • 47,058
  • 76
  • 251
  • 433

3 Answers3

128
NSString *_mySearchKey = @"James";
NSPredicate *_myPredicate = [NSPredicate predicateWithFormat:@"(firstname CONTAINS[cd] %@) OR (lastname CONTAINS[cd] %@)", _mySearchKey, _mySearchKey];
Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345
  • 37
    Found ! It means Case & Diacritic insensitive – Pierre de LESPINAY Feb 27 '13 at 13:48
  • 1
    @AlexReynolds why don't you use LIKE ? – onmyway133 Apr 10 '14 at 14:54
  • A better question is: Why should I use LIKE, instead? – Alex Reynolds Oct 17 '14 at 00:40
  • this is not working with empty string @"". Any suggestions? [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@", strFilter] not working when strFilter is @"" – Add080bbA May 12 '15 at 11:45
  • Check if the string is empty before running your predicate test, and handle that case separately. http://stackoverflow.com/questions/899209/how-do-i-test-if-a-string-is-empty-in-objective-c – Alex Reynolds May 12 '15 at 18:12
  • This answer will not give results as LIKE does for eg: S% give results starting with S, whereas contains will give results not starting with `S` will result listing containing S, which is not a correct result, whats the solution for that? – iphonic Jun 17 '16 at 14:52
38

The CONTAINS operator will certainly work just fine. If you're looking for a more direct correlation, then you can also use the LIKE operator (* = 0 or more characters, ? = 1 character):

NSString *_mySearchKey = @"James";
NSPredicate *_myPredicate = [NSPredicate predicateWithFormat:@"firstname LIKE '*%1$@*' OR lastname LIKE '*%1$@*'", _mySearchKey];

For reference:
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html#//apple_ref/doc/uid/TP40001795-215868

Tommy
  • 99,986
  • 12
  • 185
  • 204
Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • 6
    I know that's a long time ago, but this doesn't work, since NSPredicate doesn't substitute quoted content '%@' will stay '%@'... – Vincent Guerci Apr 03 '11 at 10:33
  • 1
    beginswith[c] does it for me but still, has anyone managed to generate a dynamic LIKE query such as '%@*' – Ege Akpinar Oct 26 '12 at 15:45
  • 10
    The trick to using like is to include the * marks in the argument. ie: `NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K LIKE[cd] %@", kMDItemDisplayName, [NSString stringWithFormat:@"*%@*", appname]];` – Richard H. Nov 26 '13 at 02:22
  • What does the 1$@ do? – shim Dec 22 '15 at 22:20
  • @shim identifies specifically the first argument. Contrast with if the author had just used `%@` twice; in that case he'd have needed to supply `_mySearchKey` twice. E.g. `NSLog(@"%1$@ %1$@", @"Hat");` will output "Hat Hat". – Tommy Feb 22 '17 at 15:31
10

Another possibility

@"firstname beginswith[c] James"

As a nice alternative to contains

Sometimes contains isn't always the right answer

M. Ryan
  • 6,973
  • 11
  • 52
  • 76