Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Configuring an NSPredicate with multiple conditions

I'm not certain how one would go about "cascading" several conditions into an NSPredicate.

I'm fairly new to Core Data and not sure if that's the right way to achieve what I am looking to do.

Here is what I am trying to do:

There is a Photo object that has a whereTook relationship to a Location object, which has an inverse of photosTookThere.

The Photo in turn has an NSNumber attribute called isFavourite.

I'd like to configure an NSFetchRequest that will first check that photosTookThere exists and if so, check each resulting Photo object and return only the ones that are set as favourites.

Here is the code so far:

request.entity = [NSEntityDescription entityForName:@"Location" inManagedObjectContext:context];
request.sortDescriptors = [NSArray arrayWithObject[NSSortDescriptorsortDescriptorWithKey:@"locationId" ascending:YES]];
request.predicate = [NSPredicate predicateWithFormat:@"photosTookThere.@count != 0"];

How would I cascade the second condition into the predicate and return the correct results?

like image 455
Will Avatar asked May 14 '11 20:05

Will


3 Answers

Just put each condition inside of parentheses and connect them with AND.

[NSPredicate predicateWithFormat:@"(photosTookThere.@count != 0) AND (isFavourite == %@)", [NSNumber numberWithBool:YES]];

I'd also recommend changing the name of your "whereTook" relationship to "location", and your "photosTookThere" to simply "photos", that's more in line with convention.

like image 172
Mark Leonard Avatar answered Nov 19 '22 12:11

Mark Leonard


I eventually was able to solve this using a subquery:

request.predicate = [NSPredicate predicateWithFormat:
                         @"(photosTookThere.@count !=0) AND SUBQUERY(photosTookThere, $Photo, $Photo.isFavourite==1).@count >0"
                         ];
like image 41
Will Avatar answered Nov 19 '22 13:11

Will


You can very simply use AND and OR in your predicate much like you would if you were specifying a "where" condition in an SQL statement. To check for a NULL, which it looks like you want when comparing against "whereTook", you can compare to nil (whereTook = nil).

like image 6
pzearfoss Avatar answered Nov 19 '22 12:11

pzearfoss