NSPredicate - filtering values based on a BOOLEAN stored value

38,342

Solution 1

This isn't really specific to NSPredicate... Whenever you have %@ in a format string, the corresponding value must be a pointer to an object, and BOOL doesn't qualify. So instead of passing YES, pass [NSNumber numberWithBool: YES].


In newer versions of Xcode and the SDKs than when I originally wrote the answer, you can use @YES instead of [NSNumber numberWithBool: YES].

Solution 2

From Apple's documentation:

Boolean Values

You specify and test for equality of Boolean values as illustrated in the following examples:

NSPredicate *newPredicate =
    [NSPredicate predicateWithFormat:@"anAttribute == %@", [NSNumber numberWithBool:aBool]];
NSPredicate *testForTrue =
    [NSPredicate predicateWithFormat:@"anAttribute == YES"];

However, something that caught me out:

Be sure to untick the Optional entity attribute and set a Default Value of YES or NO, otherwise the column will be empty (null?) and the above predicates will not match rows which are not explicitly set.

I used the great app sqllitebrowser to diagnose this one, by looking at the resulting simulator database.

Solution 3

If you know you're looking for a YES (and therefore don't need to switch between YES or NO in different situations), this worked for me:

[NSPredicate predicateWithFormat:@"isFavorite == 1"]

Solution 4

For me, on SWIFT 3.0 use NSNumber and %@ didn't work, I had to use integer values:

NSPredicate(format: "yourAttributeName == %i", yourBooleanValue ? 1 : 0)

Solution 5

swift 3 version worked great for me:

 let predicate = NSPredicate(format: "isFriend == %@" ,NSNumber(booleanLiteral: false))

following @scipilot answer the bool shouldn't be an optional. thanks for that!

Share:
38,342
Lance
Author by

Lance

Updated on July 18, 2022

Comments

  • Lance
    Lance almost 2 years

    I have a core data model object called Entry. In this I have an attribute IsFavorite.

    I would like to use an NSPredicate to filter the results of my NSFetchedResultsController.

    Currently I am getting EXC_BAD_ACCESS when the fetch executes.

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate. 
    
    NSEntityDescription *thisEntry = [NSEntityDescription entityForName:@"Entry" inManagedObjectContext:managedObjectContext_];
    [fetchRequest setEntity:thisEntry];
    
    NSPredicate *fetchPredicate = [NSPredicate predicateWithFormat:@"Entry.isFavorite == %@", [NSNumber numberWithBool: YES]];
    
    [fetchRequest setPredicate:predicate];
    
    
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
    aFetchedResultsController.delegate = self;
    
    
    NSError *error = nil;
    if (![aFetchedResultsController performFetch:&error]) {
        NSlog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
    

    IF I remove the line that sets the predicate on the fetchRequest, my code executes perfectly.

    I am clearly n00bin out on the predicate but have had much trouble trying to find out how to perform operations on a BOOLEAN value from a core data model object. It is noted that there are answers on how to do this with a string or int value but I can't find a BOOLEAN example.

    Many thanks !

  • Lance
    Lance almost 14 years
    I've updated my code above - which still crashes with EXC_BAD_ACCESS :( Will it be Entity.Attribute =? as I have written? or just the Attribute =?
  • T. Markle
    T. Markle about 13 years
    This worked for me if I used the NSNumber description like this [[NSNumber numberWithBool: NO] description];
  • KETAN
    KETAN almost 12 years
    it should be for a dynamic value.
  • zekel
    zekel almost 12 years
    @T. Markle The description method is called when stringWithFormat asks an object for its string representation. You should be able to use the NSNumber instance without that description call.
  • brodney
    brodney about 11 years
    @KETAN If you know you're looking for YES, then @"isFavorite == YES" will work.
  • OMGPOP
    OMGPOP over 10 years
    i think you should use "%@", @YES
  • scipilot
    scipilot over 9 years
    Sorry @János I don't know much Swift yet.
  • fir
    fir about 9 years
    Thanks a lot for pointing to "Be sure to untick the Optional entity attribute". Saved my hours!
  • scipilot
    scipilot about 9 years
    Glad to help! I spent hours on it... now I pay more attention to that right-hand panel, I'd kind of ignored it till then.
  • fir
    fir about 9 years
    Me too, before yesterday :)
  • jacob bullock
    jacob bullock almost 9 years
    Non optional booleans fixed a big problem i was having. seems to me that checking for boolAttribute != YES should work, but it didn't until i set default values on the field
  • Juan Catalan
    Juan Catalan over 8 years
    Thanks for the tip on the Optional and default value, you saved my day!