Заменить имя поля в шаблоне NSPredicate - PullRequest
2 голосов
/ 03 января 2012

Мне нужно построить динамические NSP-предикаты.Я нашел очень удобным использовать строковый файл, где я могу применить переменную подстановки.Это то, что я сделал в файле.

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 для ключа, но, кажется, нет способа сделать это со словарем.

спасибо

1 Ответ

2 голосов
/ 03 января 2012

Итак, я не знаю встроенного способа сделать это. Тем не менее, это довольно просто написать самому. Вы можете легко написать метод категории NSPredicate, который заменяет переменные, начинающиеся с KEY_, на выражение пути ключа, например:

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

предупреждение: набрано в браузере, не скомпилировано, yadda yadda

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...