NSMetadataQueryDidUpdateNotification вызывается несколько раз
Я включил 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]) {
....
}
а кажется работа, что вы думаете? Я могу обрабатывать все время, когда есть изменения, или я могу пропустить таким образом некоторые уведомления?
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);
}
Есть также ключи, чтобы получить процент загрузки и выгрузки.
Если вы хотите обработать уведомление один раз, вы можете проверить, что файл загружен.