Romowski Romowski - 1 month ago 4x
iOS Question

Multiple NSPredicate

I'm trying to prepare multiple search in my CoreData entity Recipes. There are parameters by which I would like to prepare fetch.

Recipes attributes:

@property (nonatomic, retain) NSNumber * difficulty;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * code; //like identifier
@property (nonatomic, retain) NSNumber * prepTime;

Ingredients is a separate entity with the list of ingredients.

Join entity contains ingredientCode, recipeCode, count.

getArrayOfJoinDataWithIngredients fetches join entity and returns NSArray of codes of recipes which contains some of input ingredient.

Here is my code:

- (IBAction)callRecipeFetch:(id)sender
NSString *predicateString = @"";

NSArray *codes = [[NSArray alloc] init]; codes = nil;
if ([paramController.ingredientsForSearchArray count] > 0) {
NSMutableArray *ingredientsArray = [[NSMutableArray alloc] init];
for (Ingredients *ingredient in paramController.ingredientsForSearchArray) {
[ingredientsArray addObject:ingredient.code];
MainTabController *mainTabController = [[MainTabController alloc] init];
codes = [mainTabController getArrayOfJoinDataWithIngredients:ingredientsArray];

NSString *ingrSet = [NSString stringWithFormat:@"(code IN %@)", codes];
predicateString = [predicateString stringByAppendingString:ingrSet];

NSString *diff;
if ([predicateString isEqualToString:@""]) {
diff = [NSString stringWithFormat:@"(difficulty <= %d)", paramController.diff.selectedSegmentIndex + 1];
else diff = [NSString stringWithFormat:@" AND (difficulty <= %d)", paramController.diff.selectedSegmentIndex + 1];
predicateString = [predicateString stringByAppendingString:diff];

NSString *timeString = [NSString stringWithFormat:@" AND (%d =< prepTime) AND (prepTime <= %d)", paramController.rangeSlider.leftValue, paramController.rangeSlider.rightValue];
predicateString = [predicateString stringByAppendingString:timeString];

if (paramController.categoryCode) {
NSString *categoryString = [NSString stringWithFormat:@" AND (inCategory = %@)", paramController.categoryCode];
predicateString = [predicateString stringByAppendingString:categoryString];

NSPredicate *predicate = [NSPredicate predicateWithFormat: predicateString];
[resultController findRecipesWithPredicate:predicate];

The full predicateString is
@"(code IN (\n 1,\n 3\n)) AND (difficulty <= 5) AND (0 =< prepTime) AND (prepTime <= 28800) AND (inCategory = 12)"

Now I have an error in predicate part (code IN %@) when I prepare NSPredicate with code:

NSPredicate *predicate = [NSPredicate predicateWithFormat: predicateString];


Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "(code IN (
)) AND (difficulty <= 5) AND (0 =< prepTime) AND (prepTime <= 28800) AND (inCategory = 12)"'

How to correctly make predicate with IN operator. Thanks for all advices.


use NSCompoundPredicate for your multiple predicates, you can refer NSCompoundPredicate Class Reference

something like this:

NSPredicate * andPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:predicate1,predicate2,predicate3,nil]];