Objective c 目标C查找器标签搜索
自Mavericks以来,OSX在Finder中引入了标记 我想知道是否有任何简单的方法可以搜索带有给定标记的所有文件。 例如,获取某个目录中可能标记有收藏夹的所有文件。 我知道我可以使用NSURL从单个文件中获取标签。使用它,我可以通过迭代目录和文件来查询整个文件系统。Objective c 目标C查找器标签搜索,objective-c,macos,tags,osx-mavericks,osx-yosemite,Objective C,Macos,Tags,Osx Mavericks,Osx Yosemite,自Mavericks以来,OSX在Finder中引入了标记 我想知道是否有任何简单的方法可以搜索带有给定标记的所有文件。 例如,获取某个目录中可能标记有收藏夹的所有文件。 我知道我可以使用NSURL从单个文件中获取标签。使用它,我可以通过迭代目录和文件来查询整个文件系统。 但是我想知道Objective C API是否有更快的实现方法。谢谢@Volker。这让我走上了正确的道路。 但直到我花了三个小时编写了一个框架,该框架将遍历每个文件,检查它是否与标记匹配,这是一种效率极低的方法 因此,这里有
但是我想知道Objective C API是否有更快的实现方法。谢谢@Volker。这让我走上了正确的道路。 但直到我花了三个小时编写了一个框架,该框架将遍历每个文件,检查它是否与标记匹配,这是一种效率极低的方法 因此,这里有一个类,它将搜索并返回用给定标记标记的所有文件 FindTaggedFiles.h
@interface FindTaggedFiles : NSObject
{
@private NSString* _tag;
@private NSMetadataQuery* query;
}
-(id)initWithTag:(NSString*)tag withHandler:(void(^)(NSArray*))handler;
-(void)startSearch;
@end
FindTaggedFiles.m
@interface FindTaggedFiles()
@property (copy) void (^completionHandler)(NSArray*);
@end
@implementation FindTaggedFiles
-(id)initWithTag:(NSString *)tag withHandler:(void (^)(NSArray *))handler
{
self = [super init];
_completionHandler = handler;
self->_tag = tag;
return self;
}
-(void)startSearch
{
query = [[NSMetadataQuery alloc]init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidUpdate:) name:NSMetadataQueryDidUpdateNotification object:query];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(initalGatherComplete:) name:NSMetadataQueryDidFinishGatheringNotification object:query];
NSPredicate *searchPredicate;
NSString* predicate = [NSString stringWithFormat:@"kMDItemUserTags == '%@'", self->_tag ];
searchPredicate=[NSPredicate predicateWithFormat:predicate];
[query setPredicate:searchPredicate];
NSArray *searchScopes;
searchScopes=[NSArray arrayWithObjects:NSMetadataQueryUserHomeScope,nil];
[query setSearchScopes:searchScopes];
NSSortDescriptor *sortKeys=[[NSSortDescriptor alloc] initWithKey:(id)kMDItemDisplayName ascending:YES];
[query setSortDescriptors:[NSArray arrayWithObject:sortKeys]];
[query startQuery];
}
- (void)queryDidUpdate:sender;
{
NSLog(@"A data batch has been received");
}
- (void)initalGatherComplete:sender;
{
[query stopQuery];
NSMutableArray* files = [[NSMutableArray alloc]init];
NSUInteger i=0;
for (i=0; i < [query resultCount]; i++) {
NSMetadataItem *theResult = [query resultAtIndex:i];
[files addObject:theResult];
}
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidUpdateNotification object:query];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:query];
self->query=nil;
_completionHandler(files);
}
NSMetaDataQuery是异步工作的,所以我设计这个类需要一个异步块作为init方法中的处理程序代码。但是,在文档中,我相信它提到了您不必异步运行搜索
我的课是一个改编的
还要注意:这不会在特定目录中搜索。元数据查询在特定范围内运行。作用域可以是用户的主目录(如本例中所示)、用户的iCloud、所有连接的驱动器以及其他几个驱动器。我在上面的“限制搜索范围”链接的文档中介绍了具体内容
我相信您可以进一步自定义查询,将其限制在一个目录中。作为起点,请参阅如何从代码中执行聚光灯搜索:-我正在使用它搜索文件名,但从未查看过标记。可能是通过kMDItemFSLabel…您的代码有一个问题:它在收到初始回调后停止查询。这并不像我看到的那样好,特别是在网络卷上搜索时,初始回调不会返回任何结果,但只有querydiddupdate:callback会返回结果。
FindTaggedFiles* finder = [[FindTaggedFiles alloc]initWithTag:@"Disneyland" withHandler:^(NSArray* files){
//do something with the files
}];
[finder startSearch];