1

我正在尝试NSMetadataQueryDidUpdateNotification在 OS X 应用程序上启动并运行,以在我的 iCloud 通用容器中的文件更新时提醒我。我一直在做很多研究(包括阅读其他 Stack 答案,例如thisthisthisthis),但似乎我仍然没有完全正确。

我有一个从 NSDocument 子类化的“CloudDocument”对象,它在 H 中包含以下代码:

@property (nonatomic, strong) NSMetadataQuery *alertQuery;

这是 M 文件:

@synthesize alertQuery;

-(id)init {
    self = [super init];
    if (self) {
        if (alertQuery) {
            [alertQuery stopQuery];
        } else {
            alertQuery = [[NSMetadataQuery alloc]init];
        }

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidUpdate:) name:NSMetadataQueryDidUpdateNotification object:nil];
        NSLog(@"Notification created");

        [alertQuery startQuery];
    }
    return self;
}

-(void)queryDidUpdate:(NSNotification *)notification {
    NSLog(@"Something changed!!!");
}

根据我的最佳理解,如果一个预先存在的查询正在运行,那应该停止一个预先存在的查询,设置一个通知以通知对 ubiquity 容器的更改,然后启动查询,以便它从这里开始监视更改。

除了,显然情况并非如此,因为我Notification created在启动时进入了日志,但Something changed!!!在我更改 iCloud 文档时从未登录。

谁能告诉我我错过了什么?如果你超级棒,你会帮我提供一些代码示例和/或教程吗?

编辑: 如果重要/有帮助,我的无处不在的容器中只有一个文件正在同步。它被称为“笔记”,所以我使用来自以下位置的 URL 结果访问它:

+(NSURL *)notesURL {
    NSURL *url = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
    return [url URLByAppendingPathComponent:kAllNotes];
}

其中“kAllNotes”设置为#define kAllNotes @"notes".

编辑#2:通过我与 Daij-Djan 的对话,我的代码有了很多更新,所以这是我更新的代码:

@synthesize alertQuery;

-(id)init {
    self = [super init];
    if (self) {
        alertQuery = [[NSMetadataQuery alloc] init];
        if (alertQuery) {
            [alertQuery setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];

            NSString *STEDocFilenameExtension = @"*";
            NSString* filePattern = [NSString stringWithFormat:@"*.%@", STEDocFilenameExtension];
            [alertQuery setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE %@", NSMetadataItemFSNameKey, filePattern]];
        }

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidUpdate:) name:NSMetadataQueryDidFinishGatheringNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidUpdate:) name:NSMetadataQueryDidUpdateNotification object:nil];

        NSLog(@"Notification created");

        [alertQuery startQuery];
    }
    return self;
}

-(void)queryDidUpdate:(NSNotification *)notification {
    [alertQuery disableUpdates];

    NSLog(@"Something changed!!!");

    [alertQuery enableUpdates];
}
4

2 回答 2

2

你如何保存你的文件——你给它什么网址?除非你自己给它一个扩展名,否则它不会自动被赋予一个 - 所以你的*.*模式永远不会匹配一个没有扩展名的文件。尝试*作为模式,看看会发生什么。

此外,它还有助于记录 queryDidUpdate 中发生的事情,直到您准确了解发生了什么:

尝试类似:

-(void)queryDidUpdate:(NSNotification *)notification {
    [alertQuery disableUpdates];

    NSLog(@"Something changed!!!");

    // Look at each element returned by the search
    // - note it returns the entire list each time this method is called, NOT just the changes
    int resultCount = [alertQuery resultCount];
    for (int i = 0; i < resultCount; i++) {
        NSMetadataItem *item = [alertQuery resultAtIndex:i];
        [self logAllCloudStorageKeysForMetadataItem:item];
    }

    [alertQuery enableUpdates];
}

- (void)logAllCloudStorageKeysForMetadataItem:(NSMetadataItem *)item
{
    NSNumber *isUbiquitous = [item valueForAttribute:NSMetadataItemIsUbiquitousKey];
    NSNumber *hasUnresolvedConflicts = [item valueForAttribute:NSMetadataUbiquitousItemHasUnresolvedConflictsKey];
    NSNumber *isDownloaded = [item valueForAttribute:NSMetadataUbiquitousItemIsDownloadedKey];
    NSNumber *isDownloading = [item valueForAttribute:NSMetadataUbiquitousItemIsDownloadingKey];
    NSNumber *isUploaded = [item valueForAttribute:NSMetadataUbiquitousItemIsUploadedKey];
    NSNumber *isUploading = [item valueForAttribute:NSMetadataUbiquitousItemIsUploadingKey];
    NSNumber *percentDownloaded = [item valueForAttribute:NSMetadataUbiquitousItemPercentDownloadedKey];
    NSNumber *percentUploaded = [item valueForAttribute:NSMetadataUbiquitousItemPercentUploadedKey];
    NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];

    BOOL documentExists = [[NSFileManager defaultManager] fileExistsAtPath:[url path]];

    NSLog(@"isUbiquitous:%@ hasUnresolvedConflicts:%@ isDownloaded:%@ isDownloading:%@ isUploaded:%@ isUploading:%@ %%downloaded:%@ %%uploaded:%@ documentExists:%i - %@", isUbiquitous, hasUnresolvedConflicts, isDownloaded, isDownloading, isUploaded, isUploading, percentDownloaded, percentUploaded, documentExists, url);
}
于 2013-06-16T11:49:43.127 回答
1

你永远不会分配你的 alertQuery ....

你需要分配的地方,为它初始化一个 NSMetaDataQuery

例子


NSMetadataQuery* aQuery = [[NSMetadataQuery alloc] init];
if (aQuery) {
    // Search the Documents subdirectory only.
    [aQuery setSearchScopes:[NSArray
                arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];

    // Add a predicate for finding the documents.
    NSString* filePattern = [NSString stringWithFormat:@"*"];
    [aQuery setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE %@",
                NSMetadataItemFSNameKey, filePattern]];

   // Register for the metadata query notifications.
   [[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(processFiles:)
        name:NSMetadataQueryDidFinishGatheringNotification
        object:nil];
   [[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(processFiles:)
        name:NSMetadataQueryDidUpdateNotification
        object:nil];

   // Start the query and let it run.
   [aQuery startQuery];

}

处理文件方法

== 你的 queryDidUpdate

- processFiles(NSNotification*)note {
     [aQuery disableUpdates];

     .....

     [aQuery enableUpdates];
}

注意:在那里禁用和重新启用搜索!

看:

http://developer.apple.com/library/ios/#documentation/General/Conceptual/iCloud101/SearchingforiCloudDocuments/SearchingforiCloudDocuments.html

于 2013-06-16T07:34:05.330 回答