iCloud - иногда не удается переименовать открытые документы на другом устройстве

Проблема: я работаю над документом iCloud на устройстве A, например Ipod Touch. Затем я меняю имя документа на устройстве B, например мой Mac (через Finder). Изменение передается в облако, и после паузы устройство A узнает об этом.

И затем:

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

  • Я впервые заметил это, когда добавил переопределение для PresentItemDidMoveToURL: в мой подкласс UIDocument. Переопределение надежно улавливает изменения имени, сделанные в облаке, например переименование документа на другом устройстве. Затем иногда newURL - это конечный ожидаемый URL для переименованного документа, то есть что-то разумное, из которого я могу извлечь новое имя, используя `lastPathComponent ', обновить свой интерфейс и т. Д. В других случаях newURL - это документ в каком-то другом каталог с последним компонентом пути, начинающимся с 'purg-', например purg-012fdcfbe3b3bbce6e603fdfd2f000b2cb28649e95.

     - (недействительно) PresentItemDidMoveToURL: (NSURL *) newURL;
    {
     [супер-представленныйItemDidMoveToURL: newURL];
    
    if ([(id) [самостоятельный делегат] responseToSelector: @selector (documentNameChanged :)])
     {
     [[самостоятельное делегирование] documentNameChanged: self];
     }
    }
    
  • Метод PresentItemDidMoveToURL: , похоже, не является основной причиной проблемы. Например, если я вообще не отменяю этот метод, но периодически проверяю в viewController, который следит за открытым документом, то иногда после переименования fileURL вернет новый name и иногда возвращает `purg -..... '. Таким образом, проблема, похоже, связана с тем, как обрабатывается переименование.

Обновление

Как указал al_lea, проблема здесь была связана с AccommodationPresentItemDeletionWithCompletionHandler: . Расширяя ответ 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];
       });
    }];
}

При использовании этого кода отсутствуют ложные и сбивающие с толку PresentItemDidMoveToURL: выполняются вызовы, и, кроме того, соответствующий объект может прослушивать уведомления об удалениях на других устройствах.

5
задан Sam 26 October 2014 в 22:14
поделиться