Как правильно удалить UIManagedDocument?

Кажется, я не могу найти какую-либо надежную документацию, объясняющую правильную процедуру удаления UIManagedDocument, и, в частности, ту, где включены параметры iCloud.

Я понимаю, что эта опция удалит файл по этому URL-адресу. И это, казалось бы, нормально, если iCloud не используется.

[[NSFileManager defaultManager] removeItemAtURL:fileURL error:&error];

Если используется iCloud, CoreData создает файлы повсюду, в том числе в /Document/CoreDataUbiquitySupport и в папке iCloud /CoreData. Итак, в этом случае я должен вызывать removeUbiquitousContentAndPersistentStoreAtURL для каждого магазина в UIManagedDocument до вызова [NSFileManager removeItemAtURL]. Если да, то это где-то задокументировано?

[NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:storeURL
                                                                     options:@{NSPersistentStoreUbiquitousContentNameKey:fileName,
   NSMigratePersistentStoresAutomaticallyOption:@YES,
         NSInferMappingModelAutomaticallyOption:@YES,
                          NSSQLitePragmasOption:@{ @"journal_mode" : @"DELETE" }}
                                                                       error:&error];

person Duncan Groenewald    schedule 08.10.2013    source источник


Ответы (2)


Для содержимого основных данных iCloud вы хотите вызвать статический метод removeUbiquitousContentAndPersistentStoreAtURL:options:error: в классе NSPersistentStoreCoordinator, а затем вызвать removeItemAtURL:error:

См. deleteManagedDocumentWithIdentifier: в моем проекте APManagedDocument. Это ветка ubiquitous_experiment, над которой я в настоящее время работаю, прежде чем объединить ее обратно в основную ветку.

person dtrotzjr    schedule 09.10.2013
comment
И должно ли это также удалить файл с других устройств, или у меня должна быть логика в приложении на других устройствах, чтобы определить, что файл больше не находится в iCloud, и сделать то же самое на этом устройстве? И какова логика обнаружения того, что файл был удален? Любая документация от Apple? - person Duncan Groenewald; 09.10.2013
comment
Вызов removeUbiquitousContentAndPersistentStoreAtURL:options:error удалит журналы транзакций Core Data из iCloud и удалит файл постоянного хранилища, вызов removeItemAtURL:error удалит пакет UIManagedDocument. Теперь, когда я думаю об этом, поскольку я храню свои документы в вездесущем хранилище, мне нужно сначала setUbiquitous:NO документ, чтобы iCloud тоже забыл об этом. См. сессию 207 WWDC 2013 для получения дополнительной информации о removeUbiquitousContentAndPersistentStoreAtURL:options:error - person dtrotzjr; 09.10.2013
comment
Конечно, но что происходит на других устройствах, когда на них запускается приложение? Имея в виду, что у них, вероятно, все еще есть рабочая копия базы данных, я не вижу уведомления в документах для Core Data, чтобы сказать нам: «Ой, кто-то удалил все в облаке, что вы хотите сделать сейчас: а) построить создать новую копию и поместить ее обратно в облако, б) сохранить свою копию и сделать ее только локальной, в) тоже удалить свою копию или г) позволить нам решить‹злая ухмылка› ? - person Duncan Groenewald; 10.10.2013
comment
Это просто совершенно странно - теперь у меня есть и Mac в сети !! Это безумие, я просто открываю свои существующие файлы sqlite, а затем запускаю миграцию файла, и все, они в облаке, они даже сами никуда не перемещаются. Готово, капут! Слишком легко! Мне пришлось отключить песочницу, чтобы открыть любой файл на рабочем столе. Core Data создает папку CoreDataUbiquitySupport в том же каталоге, что и документ, в котором есть резервные хранилища и прочее. Конечно, это невозможно, они сделали это так просто. - person Duncan Groenewald; 10.10.2013
comment
Вы смотрели видео WWDC? у них есть обратный вызов, который происходит, когда будет удалено и/или изменено хранилище persistenceStore, а приложение все еще работает. - person dtrotzjr; 10.10.2013
comment
Да, но у меня сложилось впечатление, что это было только во время запуска! Но перечитывая стенограмму еще раз... Теперь я должен упомянуть, что это особый случай. Вы будете видеть эти уведомления только во время нашего асинхронного процесса установки, если на диске нет файла постоянного хранилища или произошли изменения в учетной записи iCloud или содержимом контейнера с момента последнего запуска. - person Duncan Groenewald; 10.10.2013
comment
Круто, я забыл установить параметры persistenceStore перед открытием перед удалением, но теперь это работает нормально. Я только что перевел кучу файлов с рабочего стола в iCloud, и все они тоже перешли нормально, а некоторые из них весят около 100 МБ. - person Duncan Groenewald; 10.10.2013

Вот мои два цента по этому вопросу. Я пробовал то, что рекомендовал dtrotzjr, и не имел большого успеха. Кажется, что removeUbiquitousContentAndPersistentStoreAtURL:options:error: отлично подходит для очистки данных в UIManagedDocument, но папка Logs все еще там, как и остатки файла, который я пытаюсь удалить. Вот более простой способ полного удаления UIManagedDocument из iCloud или Local Docs:

+ (void)deleteDocumentURL:(NSURL *)url{
    //if we have an iCloud Document, remove it from the UbiquitouseKeyValueStore
    if ([self isiCloudURL:url]) {
        [[NSUbiquitousKeyValueStore defaultStore] removeObjectForKey:[url lastPathComponent]];
    }

    //do the delete on another thread
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
        NSError *coordinationError;

        [coordinator coordinateWritingItemAtURL:url
                                    options:NSFileCoordinatorWritingForDeleting
                                      error:&coordinationError
                                 byAccessor:^(NSURL *newURL) {
         NSError *removeError;
        //code for performing the delete
        [[NSFileManager defaultManager] removeItemAtURL:newURL error:&removeError];

        //if we have an iCloud file...
        if ([self isiCloudURL:url]) {
            //remove log files in CoreData directory in the cloud
            NSURL *changeLogsURL = [[self urlForiCloudLogFiles] URLByAppendingPathComponent:[url lastPathComponent]];
                [[NSFileManager defaultManager] removeItemAtURL:changeLogsURL error:&removeError];
            }
        }];
    });
}

Это в значительной степени код из курса Стэнфорда CS193 2012 года + удаление папки changeLogs, и он работает с локальными документами и документами iCloud. Пожалуйста, дайте мне знать, если вы обнаружите какие-либо проблемы с выполнением удаления таким образом.

person Nathan Bruno    schedule 11.12.2013
comment
взгляните на эту ссылку, где я разместил несколько примеров кода и демо-видео о том, как я заставил его работать достаточно надежно. Он показывает создание и очистку локальных каталогов и каталогов iCloud.ossh.com.au/design-and-technology/software-development/. - person Duncan Groenewald; 12.12.2013
comment
Круто, спасибо Дункан. Эта документация выглядит очень многообещающе :) - person Nathan Bruno; 18.12.2013