2012-01-03 33 views
2

我需要構建動態NSPredicates。我發現使用字符串文件非常方便,我可以在其中應用替換變量。這是我在文件中所做的。在NSPredicate模板中替換字段名稱

start<=$START AND end>=$END 

,這是駐留在工具方法的代碼片段:

-(NSPredicate*)predicateWithName:(NSString*)name andVariables:(NSDictionary*)dict { 
    NSURL *queryFile = [[NSBundle mainBundle] URLForResource:name withExtension:@"query"]; 
    //... 
    NSString *query = [NSString stringWithContentsOfURL:queryFile encoding:NSStringEncodingConversionAllowLossy error:&err]; 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:query]; 
    return [predicate predicateWithSubstitutionVariables:dict]; 
} 

它們都工作得非常好,但現在我需要添加一個充滿活力的領域中,基於一些條件我想要查詢特定的字段,但我找不到一種方法來完成此操作。查詢文件將變成:

start<=$START AND end>=$END AND $FIELD_NAME==1 

$ FIELD_NAME名獲得取代的引號和查詢不工作。我知道我可以使用%K作爲關鍵字,但似乎沒有辦法用字典來做到這一點。

感謝

回答

2

所以,沒有內置的方法,我知道做到這一點。但是,編寫自己很簡單。你可以很容易地編寫替換開始KEY_一個關鍵路徑表達式,像這樣的變量的NSPredicate類方法:

- (NSPredicate *)predicateWithEnhancedSubstitutionVariables:(NSDictionary *)vars { 
    if ([self isKindOfClass:[NSCompoundPredicate class]]) { 
    // recurse for compound predicates 
    NSCompoundPredicate *compound = (NSCompoundPredicate *)self; 
    NSMutableArray *subpredicates = [NSMutableArray array]; 
    for (NSPredicate *subpredicate in [compound subpredicates]) { 
     NSPredicate *new = [subpredicate predicateWithEnhancedSubstitutionVariables:vars]; 
     [subpredicates addObject:new]; 
    } 
    return [[[NSCompoundPredicate alloc] initWithType:[compound compoundPredicateType] 
             subpredicates:subpredicates] autorelease]; 
    } else { 
    NSPredicate *final = self; 
    // on comparison predicates, pull out the left and right expressions 
    NSComparisonPredicate *comparison = (NSComparisonPredicate *)self; 
    NSExpression *left = [comparison leftExpression]; 

    // substitute, if appropriate 
    if ([left expressionType] == NSVariableExpressionType) { 
     NSString *variable = [left variable]; 
     if ([variable hasPrefix:@"KEY_"]) { 
     NSString *replacement = [vars objectForKey:variable]; 
     if (replacement) { 
      left = [NSExpression expressionForKeyPath:replacement]; 
     } 
     } 
    } 

    // substitute, if appropriate 
    NSExpression *right = [comparison rightExpression]; 
    if ([right expressionType] == NSVariableExpressionType) { 
     NSString *variable = [right variable]; 
     if ([variable hasPrefix:@"KEY_"]) { 
     NSString *replacement = [vars objectForKey:variable]; 
     if (replacement) { 
      right = [NSExpression expressionForKeyPath:replacement]; 
     } 
     } 
    } 

    // build and return the appropriate comparison predicate 
    if (left != [comparison leftExpression] || right != [comparison rightExpression]) { 
     if ([comparison customSelector] != NULL) { 
     final = [NSComparisonPredicate predicateWithLeftExpression:left 
                rightExpression:right 
                customSelector:[comparison customSelector]]; 
     } else { 
     final = [NSComparisonPredicate predicateWithLeftExpression:left 
                rightExpression:right 
                  modifier:[comparison comparisonPredicateModifier] 
                   type:[comparison predicateOperatorType] 
                  options:[comparison options]]; 
     } 
    } 
    return [final predicateWithSubstitutionVariables:vars]; 
    } 
} 

有了這個,你應該能夠做到:

NSPredicate *p = [NSPredicate predicateWithFormat:@"$KEY_DATE = $DATE"]; 
NSDictionary *d = [NSDictionary dictionaryWithObjectsAndKeys:@"myDateProperty", @"KEY_DATE", aDate, @"date", nil]; 

p = [p predicateWithEnhancedSubstitutionVariables:d]; 

並獲得回來,如果你做了一個斷言:

NSPredicate *p = [NSPredicate predicateWithFormat:@"myDateProperty = %@", aDate]; 

警告:在瀏覽器中,沒有編譯類型,內容非常重要