iCloud - иногда не удается переименовать открытые документы на другом устройстве - PullRequest
5 голосов
/ 28 декабря 2011

Проблема: я работаю над документом 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: совершенных вызовов и, кроме того, соответствующий объект может прослушивать уведомления об удалениях на других устройствах.

1 Ответ

6 голосов
/ 13 мая 2012

Этот тип URL появляется, когда UIDocument открывается на локальном компьютере и удаляется с удаленного устройства:

file://localhost/var/mobile/Library/Mobile%20Documents/.ubd/peer-43A0AEB6-84CE-283E-CA39-FCC4EF3BC8F8-v23/ftr/purg-

Вам нужно сначала закрыть документ, прежде чем он будет удален - определите это в NSFilePresenter's accommodatePresentedItemDeletionWithCompletionHandler:

...