【问题标题】:Mac Spotlight-API: how to search email's "to", "from" or "subject" fieldsMac Spotlight-API:如何搜索电子邮件的“收件人”、“发件人”或“主题”字段
【发布时间】:2011-12-02 05:55:17
【问题描述】:

目前我有搜索电子邮件正文的 Spotlight-api 代码。我正在使用NSMetadataQuery 并为"kMDItemTextContent like[c] %@" 创建谓词。当请求的“搜索词”在电子邮件正文中时,这可以正常工作。

在 Spotlight 应用程序(右上角的放大镜图标)中,如果我输入“to: john”,我将获得“to”字段包含单词“john”的电子邮件列表(例如,某些电子邮件地址的一部分 john@something。 com)。

我尝试通过添加"kMDItemRecipients""kMDItemRecipientEmailAddresses""kMDItemAuthors""kMDItemAuthorEmailAddresses""kMDItemSubject" 类型的附加谓词来使用[NSCompoundPredicate orPredicateWithSubpredicates:] 实现此目的。 不幸的是,这不会返回所需的电子邮件。

有谁知道如何使用 Spotlight-API 实现这一目标?

下面是我的代码:

NSString *predicateFormat = @"kMDItemTextContent like[c] %@";
NSPredicate *predicateToRun = [NSPredicate predicateWithFormat:predicateFormat, self.searchKey];

NSString *predicateFormat1 = @"kMDItemTitle like[c] %@";
NSPredicate *predicateToRun1 = [NSPredicate predicateWithFormat:predicateFormat1, self.searchKey];

NSString *predicateFormat2 = @"kMDItemAuthorEmailAddresses like[c] %@";
NSPredicate *predicateToRun2 = [NSPredicate predicateWithFormat:predicateFormat2, self.searchKey];

NSString *predicateFormat3 = @"kMDItemAuthors like[c] %@";
NSPredicate *predicateToRun3 = [NSPredicate predicateWithFormat:predicateFormat3, self.searchKey];

NSString *predicateFormat4 = @"kMDItemRecipientEmailAddresses like[c] %@";
NSPredicate *predicateToRun4 = [NSPredicate predicateWithFormat:predicateFormat4, self.searchKey];

NSString *predicateFormat5 = @"kMDItemRecipients like[c] %@";
NSPredicate *predicateToRun5 = [NSPredicate predicateWithFormat:predicateFormat5, self.searchKey];

NSString *predicateFormat6 = @"kMDItemSubject like[c] %@";
NSPredicate *predicateToRun6 = [NSPredicate predicateWithFormat:predicateFormat6, self.searchKey];

NSUInteger options = (NSCaseInsensitivePredicateOption|NSDiacriticInsensitivePredicateOption);
NSPredicate *compPred = [NSComparisonPredicate
                         predicateWithLeftExpression:[NSExpression expressionForKeyPath:@"*"]
                         rightExpression:[NSExpression expressionForConstantValue:self.searchKey]
                         modifier:NSDirectPredicateModifier
                         type:NSLikePredicateOperatorType
                         options:options];

predicateToRun = [NSCompoundPredicate orPredicateWithSubpredicates:
                     [NSArray arrayWithObjects:
                      compPred, 
                      predicateToRun, predicateToRun1, predicateToRun2, predicateToRun3, predicateToRun4,   
                      predicateToRun5, predicateToRun6, nil]];

predicateToRun = [NSCompoundPredicate andPredicateWithSubpredicates:
                  [NSArray arrayWithObjects:predicateToRun, [NSPredicate predicateWithFormat:@"(kMDItemContentType != 'public.vcard')"], nil]];

[self.query setPredicate:predicateToRun]; 

[self.query startQuery];

【问题讨论】:

    标签: objective-c macos spotlight


    【解决方案1】:

    我知道如何使用 MDQuery 执行此操作 - 我认为这更简单。

    您可以在命令行中使用与在 mdfind 中使用的基本相同的查询。

    创建一个搜索字符串,例如:(未测试)

    ((((kMDItemAuthorEmailAddresses == "*john*"cd)) || ((kMDItemAuthors == "*john*"cd))) && (kMDItemContentType == 'com.apple.mail.emlx'))
    

    也在终端 mdls /path/to/library/mail/v2/24324.emlx 将显示搜索电子邮件的内容。它是你的朋友

    注意如何连接objective c 通知。

    NSString* query = some string ;
    
    MDQueryRef mdQuery = MDQueryCreate(nil, (CFStringRef)query, nil, nil);
    
    // if something is goofy, we won't get the query back, and all calls involving a mil MDQuery crash. So return:
    if (mdQuery == nil)
        return;
    
    NSNotificationCenter* nf = [NSNotificationCenter defaultCenter];
    [nf addObserver:self selector:@selector(progressUpradeQuery:) name:(NSString*)kMDQueryProgressNotification object:(id) mdQuery];
    [nf addObserver:self selector:@selector(finishedUpradeQuery:) name:(NSString*)kMDQueryDidFinishNotification object:(id) mdQuery];
    [nf addObserver:self selector:@selector(updatedUpradeQuery:) name:(NSString*)kMDQueryDidUpdateNotification object:(id) mdQuery];
    
    // Should I run this query on the network too? Difficult decision, as I think that this will slow stuff way down.
    // But i think it will only query leopard servers so perhaps ok
    //MDQuerySetSearchScope(mdQuery, (CFArrayRef)[NSArray arrayWithObjects:(NSString*)kMDQueryScopeComputer, (NSString*)kMDQueryScopeNetwork, nil], 0);
    
    // start it
    BOOL queryRunning = MDQueryExecute(mdQuery, kMDQueryWantsUpdates); 
    if (!queryRunning)
    {
        CFRelease(mdQuery);
        mdQuery = nil;
        // leave this log message in...
        NSLog(@"MDQuery failed to start.");
        return;
    }
    

    汤姆

    【讨论】:

    • 我在使用MDQueryExecute(mdQuery, kMDQueryWantsUpdates) 时遇到了问题,所以我正在使用MDQueryExecute(mdQuery, kMDQuerySynchronous) 并且我收到了想要的电子邮件——无论如何我的处理都是在单独的线程中进行的。谢谢!
    猜你喜欢
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多