44

How can I compare two NSNumbers or a NSNumber and an Integer in an NSPredicate?

I tried:

NSNumber *stdUserNumber = [NSNumber numberWithInteger:[[NSUserDefaults standardUserDefaults] integerForKey:@"standardUser"]];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"userID == %@", stdUserNumber];

Well, this doesn't work ... anyone has an idea how to do it? I'm sure it's pretty easy but I wasn't able to find anything ...

Jonas Deichelmann
  • 3,513
  • 1
  • 30
  • 45
wolfrevo
  • 2,006
  • 2
  • 25
  • 32

2 Answers2

105

NSNumber is an object type. Unlike NSString, the actual value of NSNumber is not substitued when used with %@ format. You have to get the actual value using the predefined methods, like intValue which returns the integer value. And use the format substituer as %d as we are going to substitute an integer value.

The predicate should be,

predicateWithFormat:@"userID == %d", [stdUserNumber intValue]];
EmptyStack
  • 51,274
  • 23
  • 147
  • 178
  • Great thank you so much! Is there a list of all these %d %i %@ %... "shortcuts"? – wolfrevo Sep 24 '11 at 18:09
  • 2
    ... this shouldn't make a difference. The predicate format parser will see the `%d` in the format string, pop an `int` off the `va_list`, and then box it in an `NSNumber`. – Dave DeLong Sep 24 '11 at 19:22
  • That's strange because I also tried: fetchRequest.predicate = [NSPredicate predicateWithFormat:@"userID == %i", [[NSUserDefaults standardUserDefaults] integerForKey:@"standardUser"]]]; And that didn't work ... so it has to be the %d !? ... Anyways, it's working now :) – wolfrevo Sep 24 '11 at 22:40
  • This saved me some time for sure. Since I was writing most of the code in swift and only used %@ for defining the predicate, it totally slipped off my mind that we need to use correct format substitutes. – Kushal Ashok Aug 16 '16 at 12:10
  • 2
    Here's a list of all format specifiers: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html – wolfrevo Oct 10 '16 at 19:37
3

If you are using predicateWithSubstitutionVariables: and value you want to predicate is NSNumber with integer value then you need to use NSNumber in predicate instead of NSString as substitution value. Take a look at example:

NSPredicate *genrePredicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"genreID == $GENRE_ID"]]; //if we make only one NSPredicate if would look something like this: [NSPredicate predicateWithFormat:@"genreID == %d", [someString integerValue]];

NSPredicate *localPredicate = nil;
for(NSDictionary *genre in genresArray){
    localPredicate = [genrePredicate predicateWithSubstitutionVariables:@{@"GENRE_ID" : [NSNumber numberWithInteger:[genre[@"genre_id"] integerValue]]}];
}
Josip B.
  • 2,434
  • 1
  • 25
  • 30