Configuring an NSPredicate with multiple conditions

24,777

Solution 1

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.

Solution 2

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"
                         ];

Solution 3

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).

Share:
24,777
Will
Author by

Will

iOS Developer

Updated on December 11, 2020

Comments

  • Will
    Will over 3 years

    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?