【问题标题】:NSPredicate(s) for NSMetadataQuery to match kMDItemAccessedDates (array) containing a target date?NSMetadataQuery 的 NSPredicate(s) 以匹配包含目标日期的 kMDItemAccessedDates (array)?
【发布时间】:2012-12-30 17:20:51
【问题描述】:

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


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

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

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

【问题讨论】:

    标签: objective-c cocoa nspredicate spotlight nsmetadataquery


    【解决方案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]];
    

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

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

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

    【讨论】:

    • 这很有趣。我以前没有看过 CAST。我很高兴你能成功。
    【解决方案2】:

    好的,我认为这是您想要的方法。我在查看 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];
    

    【讨论】:

    • 嘿,现在很聪明!我一直将它们视为日期,但实际上正如您所指出的,它们也是字符串。我要试试这个。
    • 嗯。无法使其正常工作。我对 kMDItemAuthors 有类似这样的工作符号,它是一个字符串数组,所以我想知道它是否在这里不起作用,因为它们是日期……也尝试以开头以防万一(不添加“*”),也不起作用。
    猜你喜欢
    • 2013-09-02
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多