Multiple NSPredicate

谁说胖子不能爱 提交于 2019-11-30 01:32:10

问题


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

ERROR:

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

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


回答1:


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



回答2:


Addition to @Joshua's answer, you can also use NSCompoundPredicate for your OR operations like this.

Obj-C - OR

// OR Condition //

NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"X == 1"];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"X == 2"];
NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[predicate1, predicate2]];

Swift - OR

let predicate1:NSPredicate = NSPredicate(format: "X == 1")
let predicate2:NSPredicate = NSPredicate(format: "Y == 2")
let predicate:NSPredicate  = NSCompoundPredicate(orPredicateWithSubpredicates: [predicate1,predicate2] )

Swift 3 - OR

    let predicate1 = NSPredicate(format: "X == 1")
    let predicate2 = NSPredicate(format: "Y == 2")
    let predicateCompound = NSCompoundPredicate.init(type: .or, subpredicates: [predicate1,predicate2])



回答3:


It will work for you.

    NSPredicate *bPredicate;
    bPredicate = [NSPredicate predicateWithFormat:@"name contains[c] %@ OR product_price contains[c] %@ OR foodescription contains[c] %@",searchText,searchText,searchText];

NSArray *filteredArray = [getObjectsFromServiceArray filteredArrayUsingPredicate:bPredicate];


来源:https://stackoverflow.com/questions/16642934/multiple-nspredicate

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!