0

更新:我找到了答案,尽管可能还有更好的方法 - 请参阅下面添加的答案。


聚光灯导入器导入元数据,元数据是访问项目的日期数组。看起来像这样:

kMDItemAccessedDates               = (
    "2012-06-18 07:00:00 +0000",
    "2013-01-10 08:00:00 +0000",
    "2013-01-15 08:00:00 +0000"
)

我想查询在用户输入的特定日期访问的任何这些文件,但我没有找到正确的语法来执行此操作。想知道有没有可能做...

第一个问题是用户输入代表一天的日期,而不是日期和时间。

似乎我需要搜索那一天的任何日期,所以合乎逻辑:ADATE >= user_day_start && ADATE <= user_day_end

现在元数据中有一组日期,所以如果这些日期中的任何一个在 user_date 日期内,我真的希望它匹配。

如果这有效,那就太好了:

NSDate * date = [NSDate dateWithNaturalLanguageString: inWhenString];
NSDate * endDate = [NSDate dateWithTimeInterval: 86400 sinceDate: date];

predicate = [NSPredicate predicateWithFormat: 
              @"kMDItemAccessedDates between {%@, %@}", date, endDate];

但这会引发异常:

Exception detected while handling key input.
2013-01-16 03:12:57.517 Chatty[96974:403] Unknown type of NSComparisonPredicate 
  given to NSMetadataQuery 
  (kMDItemAccessedDates BETWEEN {CAST(379540800.000000, "NSDate"),
  CAST(379627200.000000, "NSDate")}) 

并且似乎它可能只适用于单个日期而不是数组。像这样将“ANY”添加到格式字符串中:"ANY kMDItemAccessedDates between {%@, %@}"......没有帮助,仍然抛出异常。

试过这个,它没有抛出异常,但也没有真正起作用:

NSPredicate *p1 = [NSPredicate predicateWithFormat: @"kMDItemAccessedDates >= %@", date ];
NSPredicate *p2 = [NSPredicate predicateWithFormat: @"kMDItemAccessedDates <= %@", endDate ];
predicate = [NSCompoundPredicate andPredicateWithSubpredicates: [NSArray arrayWithObjects: p1, p2, nil]];

想知道是否有人对如何使这项工作有任何想法......或者知道这是不可能的(比如必须全部获得它们,然后在内存中进行过滤或其他东西;真的希望不是这样 - 它可能是一个很长的列表!)。

4

2 回答 2

1

因此,又花了几个小时深入研究互联网搜索结果并尝试了一些东西,然后我开始工作了。

NSDate * userDate = [NSDate dateWithNaturalLanguageString: inWhenString];
NSDateComponents * userDateComponents = [[NSCalendar currentCalendar] components: NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate: userDate];
NSDate * dayDate = [[NSCalendar currentCalendar] dateFromComponents: userDateComponents];
dNSLog(@"date %@", dayDate );
NSString * formatStr = [NSDateFormatter dateFormatFromTemplate: @"yyyy-MM-dd" options: 0 locale: nil];
NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat: formatStr];

NSString * dayStr = [formatter stringFromDate: dayDate];
dayStr = [dayStr stringByAppendingString: @"*"];
dNSLog(@"dayString: %@", dayStr );
NSPredicate *p1 = [NSPredicate predicateWithFormat: @"%K >= CAST(%f, \"NSDate\")", @"kMDItemAccessedDates", [dayDate timeIntervalSinceReferenceDate] ];
NSPredicate *p2 = [NSPredicate predicateWithFormat: @"%K <= CAST(%f, \"NSDate\")", @"kMDItemAccessedDates", [dayDate timeIntervalSinceReferenceDate] + 86400.0f ];
predicate = [NSCompoundPredicate andPredicateWithSubpredicates: @[p1, p2]];

整个方法可能存在其他问题(基于应用程序如何更新此日期数组),这可能需要我完全做其他事情,但这似乎回答了如何仅获取在 a 上访问的项目的原始问题特定的日子。

关键是CAST(%f, \"NSDate\")我相信。

可能还有更好的方法,但我想我会把它放在这里,以防其他人四处挖掘以寻找任何线索。

于 2013-01-17T06:48:38.667 回答
0

好的,我认为这是您想要的方法。我在查看 kMDItemContentTypeTree 属性的文件文件夹上对此进行了测试,该属性是一个字符串数组,例如您的情况。基本上我将创建一个 BEGINSWITH 搜索,它将搜索该数组的值。

BEGINSWITH 搜索是 LIKE 搜索,但搜索词的末尾附加了“*”。我的想法是,您获取用户输入的日期并使用“YYYY-MM-DD”形式创建一个搜索字符串,以获取我在另一篇文章中展示的年/月/日。然后,您从这些值以该格式创建一个字符串。

现在您可以创建您的谓词并从您的 userDateString 开始这样的查询。您会注意到我使用 %K 插入 kMDItemAccessedDates 属性。

NSString* userDateString = @"2013-01-15";

NSString* queryKeyString = @"kMDItemAccessedDates";
NSString* searchDate = [userDateString stringByAppendingString:@"*"];
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"%K like %@", queryKeyString, searchDate];

// folderQuery is your NSMetadataQuery
[folderQuery setSearchScopes:[NSArray arrayWithObject:folderPath]]; // the folder you want to search
[folderQuery setPredicate:predicate];
[folderQuery startQuery];
于 2013-01-16T15:58:01.590 回答