目前我有一个搜索电子邮件正文的spotlight-api代码。我正在使用NSMetadataQuery
并为"kMDItemTextContent like[c] %@"
创建谓词。当请求“搜索期限”在电子邮件正文中时,此工作正常。
在Spotlight应用程序(右上角的放大镜图标)中,如果我输入“to:john”,我将获得其中“to”字段包含单词“john”的电子邮件列表(例如某些电子邮件地址的一部分john @ something。 COM)。
我尝试通过添加[NSCompoundPredicate orPredicateWithSubpredicates:]
,"kMDItemRecipients"
,"kMDItemRecipientEmailAddresses"
,"kMDItemAuthors"
和"kMDItemAuthorEmailAddresses"
类型的其他谓词来"kMDItemSubject"
实现此目标。
不幸的是,这不会返回所需的电子邮件。
有没有人知道如何使用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];
答案 0 :(得分:1)
我知道如何使用MDQuery执行此操作 - 我认为这更简单。
您可以使用与命令行中的mdfind基本相同的查询。
制作一个搜索字符串,如:(未经测试)
((((kMDItemAuthorEmailAddresses == "*john*"cd)) || ((kMDItemAuthors == "*john*"cd))) && (kMDItemContentType == 'com.apple.mail.emlx'))
也在终端 mdls /path/to/library/mail/v2/24324.emlx 将显示搜索电子邮件的内容。它是你的朋友
请注意您如何连接目标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;
}
汤姆