【问题标题】:NSMetadataQueryDidUpdateNotification called several timeNSMetadataQueryDidUpdateNotification 调用了几次
【发布时间】:2013-10-20 04:05:00
【问题描述】:

我在我的应用程序中启用了 iCloud UIDocument,并将文档存储在云上,文档已打包,以便接收我正在执行的 iCloud 文档更新通知:

- (void)startQuery {

    [self stopQuery];

    NSLog(@"Starting to watch iCloud dir...");

    _query = [self documentQuery];

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

    [_query startQuery];
}

- (void)stopQuery {

    if (_query) {

        NSLog(@"No longer watching iCloud dir...");

        [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidUpdateNotification object:nil];
        [_query stopQuery];
        _query = nil;
    }

}

- (NSMetadataQuery *)documentQuery {

    NSMetadataQuery * query = [[NSMetadataQuery alloc] init];
    if (query) {

        [query setSearchScopes:[NSArray arrayWithObject:
                                 NSMetadataQueryUbiquitousDocumentsScope]];

        NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K == %@",
                             NSMetadataItemFSNameKey,
                             kFILENAME];
        [query setPredicate:pred];

    }
    return query;

}

- (void)processiCloudFiles:(NSNotification *)notification {

    [_query disableUpdates];

    if ([_query resultCount] == 1) {
        NSMetadataItem *item = [_query resultAtIndex:0];
        NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];

        if (!self.folder) {
            self.folder = [[MyDocument alloc] initWithFileURL:url];
        }
        [self.folder openWithCompletionHandler:^ (BOOL success) {
            if (success) {
                NSLog(@"loadData - doc opened from cloud %i", self.folder.count);
                [self.folder closeWithCompletionHandler:^(BOOL success) {
                    NSLog(@"doc closed");
                }
                 ];
            } else {
                NSLog(@"failed to open");
            } }];

    }
}

首先我打电话给[self startQeury],问题是NSMetadataQueryDidUpdateNotification在我对文档进行更改时多次调用通知,您如何查看日志:

2013-10-12 01:43:54.933  Starting to watch iCloud dir...
2013-10-12 01:43:56.119  loadData - doc opened from cloud 56
2013-10-12 01:43:56.120  doc closed
2013-10-12 01:44:01.552  item deleted

正如您在此处看到的,我进行了更改,在下方您可以看到 spawn 4 通知:

2013-10-12 01:44:08.110  loadData - doc opened from cloud 55
2013-10-12 01:44:08.111  doc closed
2013-10-12 01:44:11.942  loadData - doc opened from cloud 55
2013-10-12 01:44:11.943  doc closed
2013-10-12 01:44:13.198  loadData - doc opened from cloud 55
2013-10-12 01:44:13.199  doc closed
2013-10-12 01:44:14.925  loadData - doc opened from cloud 55
2013-10-12 01:44:14.926  doc closed

为什么要调用几次?在我的应用程序中,我需要在更新完成后处理更改,所以我只需要一个通知...我该怎么办?

编辑: 我已经尝试过@rmaddy 在答案中的建议,我已经尝试过:

if ([[item valueForAttribute:NSMetadataUbiquitousItemIsDownloadedKey] boolValue]) {

        if (!self.folder) {
            self.tvfilesFolder = [[MyDocument alloc] initWithFileURL:url];
        }
        [self.folder openWithCompletionHandler:^ (BOOL success) {
            if (success) {
                NSLog(@"loadData - doc opened from cloud %i", self.folder.count);
                [self.folder closeWithCompletionHandler:^(BOOL success) {
                    NSLog(@"doc closed");
                }
                 ];
            } else {
                NSLog(@"failed to open");
            } }];
    }

但我又遇到了问题,这是日志:

2013-10-12 10:35:26.084 Starting to watch iCloud dir...
2013-10-12 10:35:30.306 loadData - doc opened from cloud 54
2013-10-12 10:35:30.307 doc closed

然后我编辑了一个文档,这是日志:

2013-10-12 10:35:53.233 loadData - doc opened from cloud 54
2013-10-12 10:35:53.235 doc closed
2013-10-12 10:35:56.703 loadData - doc opened from cloud 54
2013-10-12 10:35:56.704 doc closed
2013-10-12 10:35:58.489 loadData - doc opened from cloud 54
2013-10-12 10:35:58.490 doc closed

我该怎么办?

编辑 2:

我试过这个:

if ([[item valueForAttribute:NSMetadataUbiquitousItemIsDownloadedKey] boolValue] && [[item valueForAttribute:NSMetadataUbiquitousItemIsUploadedKey] boolValue]) {
....
}

而且看起来很有效,你觉得呢?我可以随时处理有变化,或者我可以通过这种方式错过一些通知?

【问题讨论】:

    标签: ios objective-c icloud nsnotificationcenter uidocument


    【解决方案1】:

    调用通知的原因有很多。文件首次上传到 iCloud 以及从 iCloud 下载文件的时间。您还可以获得有关上传和下载百分比的更新。如果您查看文件的各种属性,您可以看到所有这些。

    我使用一点调试方法来记录每个元数据项:

    - (void)echoMetadataItem:(NSMetadataItem *)item {
        NSString *path = [item valueForAttribute:NSMetadataItemPathKey];
        NSString *display = [item valueForAttribute:NSMetadataItemDisplayNameKey];
        NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
        NSString *name = [item valueForAttribute:NSMetadataItemFSNameKey];
        NSNumber *downloaded = [item valueForAttribute:NSMetadataUbiquitousItemIsDownloadedKey];
        NSNumber *downloading = [item valueForAttribute:NSMetadataUbiquitousItemIsDownloadingKey];
        NSNumber *uploaded = [item valueForAttribute:NSMetadataUbiquitousItemIsUploadedKey];
        NSNumber *uploading = [item valueForAttribute:NSMetadataUbiquitousItemIsUploadingKey];
        NSDate *createData = [item valueForAttribute:NSMetadataItemFSCreationDateKey];
        NSDate *updateDate = [item valueForAttribute:NSMetadataItemFSContentChangeDateKey];
        NSNumber *hasConflicts = [item valueForAttribute:NSMetadataUbiquitousItemHasUnresolvedConflictsKey];
    
        RMLogInfo(@"Metadata item name: %@, display: %@, path: %@, url: %@, ded: %@, ding: %@, ued:%@, uing: %@, created: %@, updated: %@, conflicts: %@", name, display, path, url, downloaded, downloading, uploaded, uploading, createData, updateDate, hasConflicts);
    }
    

    还有获取上传下载百分比的键。

    如果您想处理一次通知,您可以检查文件是否已下载。

    【讨论】:

    • 不起作用,我已经尝试使用这个键:NSMetadataUbiquitousItemIsDownloadedKey,看看这个问题,我已经用日志编辑了它,似乎没有任何变化......
    • @Piero 此键NSMetadataUbiquitousItemDownloadingStatusKey 已被弃用,您可以改用NSMetadataUbiquitousItemDownloadingStatusKey
    猜你喜欢
    • 2014-02-22
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多