Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 目标C查找器标签搜索_Objective C_Macos_Tags_Osx Mavericks_Osx Yosemite - Fatal编程技术网

Objective c 目标C查找器标签搜索

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。这让我走上了正确的道路。 但直到我花了三个小时编写了一个框架,该框架将遍历每个文件,检查它是否与标记匹配,这是一种效率极低的方法 因此,这里有

自Mavericks以来,OSX在Finder中引入了标记

我想知道是否有任何简单的方法可以搜索带有给定标记的所有文件。 例如,获取某个目录中可能标记有收藏夹的所有文件。 我知道我可以使用NSURL从单个文件中获取标签。使用它,我可以通过迭代目录和文件来查询整个文件系统。
但是我想知道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];