2013-05-20 74 views
15

我試圖在我的CoreData實體中準備多個搜索食譜。有我想要準備抓取的參數。Multiple NSPredicate

食譜屬性:

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

成分與配料表一個獨立的實體。

加入實體包含ingredientCoderecipeCode計數

getArrayOfJoinDataWithIngredients加入實體和返回的碼食譜其中包含了一些輸入成分的NSArray。

這裏是我的代碼:

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

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

現在我有謂語部分(代碼%@)一個錯誤,當我用代碼編寫NSPredicate:

NSPredicate *predicate = [NSPredicate predicateWithFormat: predicateString]; 

錯誤:

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)"' 

如何正確預測運算符IN運算符。感謝所有的建議。

回答

39

使用NSCompoundPredicate您的多個謂詞,你可以參考NSCompoundPredicate Class Reference

是這樣的:

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

@Romowski嘿夥計更新了我的答案,並舉了一個例子 – Joshua

+0

謝謝!有用!!! – Romowski

+0

沒問題的人。很高興它幫助:) – Joshua

12

加成@約書亞的回答,您還可以使用NSCompoundPredicate您OR操作是這樣的。

對象 - - OR

// OR Condition // 

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

斯威夫特 - OR

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

斯威夫特3 - 或

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

不錯,這是使用完整的我.. –

0

它會爲你工作。

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