Проблема: я работаю над документом iCloud на устройстве A, например, iPod Touch.Затем я изменяю название документа на устройстве B, например, на моем Mac (через Finder).Изменение переходит в облако, и после паузы устройство A узнает об этом.
И затем:
- иногда все в порядке - я поднимаюизменение имени через измененное свойство
fileURL
и может соответствующим образом обновить мой интерфейс - документ продолжает вести себя так же, как и - , иногда fileURL документа возвращается в виде чего-то вроде:
file://localhost/var/mobile/Library/Mobile%20Documents/.ubd/peer-43A0AEB6-84CE-283E-CA39-FCC4EF3BC8F8-v23/ftr/purg-012fdcfbe3b3bbce6e603fdfd2f000b2cb28649e95
Не удивительно, что этот файл не будет сохранен.
Может кто-нибудь объяснить, что происходит и как обойти это?
Фон
Смена имени штрафа NSMetadataQuery
.Так, например, я могу переименовать документы, которые не открыты, и все мои функции iCloud работают нормально.Кажется, проблема возникает только с открытыми документами.
Другие функции iCloud работают нормально, например, я могу изменить содержимое на одном устройстве, например, на моем Mac, и обнаруживать, а затем обновлять свой интерфейс надругое устройство, например мой iPod Touch, на котором открыт соответствующий документ iCloud.
Впервые я заметил это, когда добавил переопределение для presentedItemDidMoveToURL:
в свой подкласс UIDocument.Переопределение надежно фиксирует изменения имени, сделанные в облаке, например, переименование документа на другом устройстве.Тогда иногда newURL - это окончательный ожидаемый URL для переименованного документа, т.е. что-то разумное, из чего я могу извлечь новое имя, используя `lastPathComponent ', обновить мой интерфейс и т. Д. В других случаях newURL - это документ в каком-то другомкаталог с последним компонентом пути, начинающимся с 'purg-', например purg-012fdcfbe3b3bbce6e603fdfd2f000b2cb28649e95.
- (void) presentedItemDidMoveToURL:(NSURL *) newURL;
{
[super presentedItemDidMoveToURL: newURL];
if ([(id)[self delegate] respondsToSelector:@selector(documentNameChanged:)])
{
[[self delegate] documentNameChanged: self];
}
}
Метод presentedItemDidMoveToURL:
не является основной причиной проблемы.Например, если я вообще не отменяю этот метод, а периодически проверяю viewController, который следит за открытым документом, то иногда после переименования fileURL
возвращает новое имя и иногда он возвращает `purg -..... '.Таким образом, проблема, похоже, связана с обработкой переименования.
Обновление
Как указала al_lea, проблема здесь была связана сaccommodatePresentedItemDeletionWithCompletionHandler:
.Развернув ответ al_lea, я добавил приведенный ниже код в свой подкласс UIDocument.Это решило проблему.
- (void) accommodatePresentedItemDeletionWithCompletionHandler: (void (^) (NSError *errorOrNil)) completionHandler
{
PresentedDocument* presentedDocument = [self retain];
[presentedDocument closeWithCompletionHandler: ^(BOOL success) {
NSError* error = nil;
if (!success)
{
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not close document that is being deleted on another device",
NSLocalizedDescriptionKey, nil];
error = [NSError errorWithDomain: @"some_suitable_domain"
code: 101
userInfo: userInfo];
}
completionHandler(error); // run the passed in completion handler (required)
dispatch_async(dispatch_get_main_queue(), ^
{
[[NSNotificationCenter defaultCenter] postNotificationName: NOTIFY_presentedDocumentDeletedOnAnotherDevice
object: presentedDocument
userInfo: nil];
[presentedDocument tidyUpAfterDelete]; // app specific tidy up
[presentedDocument release];
});
}];
}
При наличии этого кода нет никаких ложных и сбивающих с толку представленныхItemDidMoveToURL: совершенных вызовов и, кроме того, соответствующий объект может прослушивать уведомления об удалениях на других устройствах.