0

我在我的应用程序中启用了 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]) {
....
}

似乎工作,你怎么看?我可以随时处理有变化,或者我可以通过这种方式错过一些通知?

4

1 回答 1

0

调用通知的原因有很多。文件首次上传到 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);
}

还有一些键可以获取上传和下载的百分比。

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

于 2013-10-12T00:14:31.263 回答