NSPredicate - filtering values based on a BOOLEAN stored value
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!
Lance
Updated on July 18, 2022Comments
-
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 almost 14 yearsI'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 about 13 yearsThis worked for me if I used the NSNumber description like this
[[NSNumber numberWithBool: NO] description];
-
KETAN almost 12 yearsit should be for a dynamic value.
-
zekel almost 12 years@T. Markle The
description
method is called whenstringWithFormat
asks an object for its string representation. You should be able to use theNSNumber
instance without thatdescription
call. -
brodney about 11 years@KETAN If you know you're looking for YES, then @"isFavorite == YES" will work.
-
OMGPOP over 10 yearsi think you should use "%@", @YES
-
scipilot over 9 yearsSorry @János I don't know much Swift yet.
-
fir about 9 yearsThanks a lot for pointing to "Be sure to untick the Optional entity attribute". Saved my hours!
-
scipilot about 9 yearsGlad 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 about 9 yearsMe too, before yesterday :)
-
jacob bullock almost 9 yearsNon 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 over 8 yearsThanks for the tip on the Optional and default value, you saved my day!