无法使用NSDates在NSPredicate中解析格式字符串

时间:2014-08-25 18:04:06

标签: objective-c nspredicate stringwithformat

我已经阅读了很多关于NSPredicate语句中可能出错的Stack Overflow帖子,但我仍然无法弄清楚我的代码有什么问题。

我正在检查用户是否正在使用某些正则表达式搜索一年。如果是的话,我会创建一个搜索,从一年的第一天到最后一天。

这是我的代码:

//Check if searchBar.text is a year
NSString *expression = @"^\\d{4}$";
NSError *error = NULL;

//Regex test
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression options:NSRegularExpressionCaseInsensitive error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:searchBar.text options:0 range:NSMakeRange(0, [searchBar.text length])];

NSString *predicateString;
if(match){

  //Search contains a year
  NSDate *startDate = [_fullFormat dateFromString:[NSString stringWithFormat:@"%@-01-01",searchBar.text]];
  NSDate *endDate = [_fullFormat dateFromString:[NSString stringWithFormat:@"%@-12-31",searchBar.text]];

  predicateString = [NSString stringWithFormat:@"(departure CONTAINS[cd] '%1$@') OR (destination CONTAINS[cd] '%1$@') OR (aircraft.aircraftRegistration CONTAINS[cd] '%1$@') OR (aircraft.makeModel CONTAINS[cd] '%1$@') OR (duration CONTAINS[cd] '%1$@') OR (remarks CONTAINS[cd] '%1$@') OR ((flightDate >= %2$@) AND (flightDate <= %3$@))",searchBar.text,startDate,endDate];

}else{
  //...
}

NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:predicateString];

记录predicateString会产生:

(departure CONTAINS[cd] '2014') OR (destination CONTAINS[cd] '2014') OR (aircraft.aircraftRegistration CONTAINS[cd] '2014') OR (aircraft.makeModel CONTAINS[cd] '2014') OR (duration CONTAINS[cd] '2014') OR (remarks CONTAINS[cd] '2014') OR ((flightDate >= 2014-01-01 07:00:00 +0000) AND (flightDate <= 2014-12-31 07:00:00 +0000))

我遇到了以下声明:

'Unable to parse the format string "(departure CONTAINS[cd] '2014') OR (destination CONTAINS[cd] '2014') OR (aircraft.aircraftRegistration CONTAINS[cd] '2014') OR (aircraft.makeModel CONTAINS[cd] '2014') OR (duration CONTAINS[cd] '2014') OR (remarks CONTAINS[cd] '2014') OR ((flightDate >= 2014-01-01 07:00:00 +0000) AND (flightDate <= 2014-12-31 07:00:00 +0000))"'

知道我做错了吗?

1 个答案:

答案 0 :(得分:2)

您不应使用stringWithFormat来构建谓词。你的predicateString 包含日期的描述字符串,例如&#34; 2014-01-01 07:00:00 + 0000&#34;,以及 predicateWithFormat无法处理。

不幸的是,predicateWithFormat无法处理位置参数,例如 stringWithFormat,这意味着您必须在必要时重复参数:

[NSPredicate predicateWithFormat:@"(departure CONTAINS[cd] %@) OR (destination CONTAINS[cd] %@) OR (aircraft.aircraftRegistration CONTAINS[cd] %@) OR (aircraft.makeModel CONTAINS[cd] %@) OR (duration CONTAINS[cd] %@) OR (remarks CONTAINS[cd] %@) OR ((flightDate >= %@) AND (flightDate <= %@))",
    searchBar.text, searchBar.text, searchBar.text, searchBar.text,
    searchBar.text, searchBar.text, startDate, endDate];

对于复杂谓词,您可能还会考虑使用NSCompoundPredicate方法 andPredicateWithSubpredicates:orPredicateWithSubpredicates: 先后建立谓词。