Я создаю новый UIManagedDocument с поддержкой iCloud следующим образом:
- Распределить и инициализировать с URL-адресом локальной песочницы
- Установите параметры постоянного хранилища для поддержки iCloud: ubiquitousContentNameKey и ubiquitousContentURL. Имя, которое я генерирую уникально, и URL-адрес указывает на мой ubiquityContainer/CoreData.
- Сохраняйте локально в песочнице с помощью метода saveToURL UIManagedDocument.
- В обработчике завершения перейдите в iCloud с помощью метода setUbiquitous FileManager.
Пока этот танец работает. (Ну вроде). После того, как я вызываю setUbiquitous, я получаю сообщение об ошибке, в котором говорится, что это НЕ ПРОШЛО, однако документ перемещается в облако. Когда это будет сделано, у меня будет новый документ в облаке. Похоже, это ошибка, так как я смог воспроизвести ее с чужим кодом.
На самом деле я создаю этот документ в «Контроллере просмотра документов», в котором перечислены все документы в облаке. Поэтому, когда обработчик окончательного завершения этого нового документа завершен, он отображается в табличном представлении благодаря NSMetadataQuery. До сих пор, я думаю, довольно стандартное использование.
Чтобы отредактировать документ, пользователь нажимает и переходит к «Контроллеру просмотра документов с одним просмотром».
В этом контроллере представления мне нужно «повторно открыть» выбранный документ, чтобы пользователь мог его редактировать.
Итак, я снова прохожу ряд шагов:
- Выделите/инициируйте UIManagedDocument с помощью URL-адреса файла — на этот раз URL-адрес находится в облаке.
- Установите параметры моего постоянного хранилища, как в шаге 2 выше, с теми же настройками.
Теперь я ПОПЫТАЮСЬ выполнить шаг 3, который заключается в том, чтобы открыть документ с диска, но это не удается. Документ находится в состоянии «Закрыт | Ошибка сохранения», и попытка открытия не удалась.
Кто-нибудь знает, почему мой документ создается "ОК", перемещается в "облако" "ОК", но не открывается сразу после следующей попытки? (Действительно, попытка в рамках этого запуска приложения - см. ниже). В частности, что может привести к созданию экземпляра UIManagedDocument, но в закрытом, недоступном для открытия состоянии?
Интересно, что если я выйду из приложения и снова запущу его, я смогу нажать, перезагрузить документ и отредактировать его.
И очень редко я могу создать, затем открыть и очень кратко отредактировать, скажем, вставить один управляемый объект, а затем он переходит в это закрытие | сохранение состояния ошибки.
ИНФОРМАЦИЯ ОБ ОШИБКЕ:
Я создал подкласс UIManagedDocument и переопределил метод -handleError:, чтобы попытаться получить больше информации, и вот что я получил (вместе с некоторыми другими журналами отладки, которые я добавил):
2012-10-05 14:57:06.000 Foundations[23687:907] Загрузилось представление контроллера представления одного документа. Документ: fileURL: file://localhost/private/var/mobile/Library/Mobile%20Documents/7PB5426XF4~com~howlin~MyApp/Documents/New%20Document%2034/ documentState: [Closed]
05.10.2012 14:57:06.052 MyApp[23687:907] Состояние документа изменено. Текущее состояние: 5 URL-адрес файла: file://localhost/private/var/mobile/Library/Mobile%20Documents/7PB5426XF4~com~howlin~MyApp/Documents/New%20Document%2034/ documentState: [Closed | Ошибка сохранения]
05.10.2012 14:57:06.057 Foundations[23687:5303] Ошибка UIManagedDocument: имя хранилища: новый документ 34 уже используется. URL-адрес магазина: file://localhost/private/var/mobile/Library/Mobile%20Documents/7PB5426XF4~com~howlin~MyApp/Documents/New%20Document%2034/StoreContent.nosync/persistentStore URL-адрес используемого магазина: file:/ /localhost/var/mobile/Applications/D423F5FF-4B8E-4C3E-B908-11824D70FD34/Documents/New%20Document%2034/StoreContent.nosync/persistentStore
2012-10-05 14:57:06.059 MyApp[23687:5303] { NSLocalizedDescription = "Имя магазина: Новый документ 34 уже используется.\n\tURL-адрес хранилища: file://localhost/private/var/mobile/ Library/Mobile%20Documents/7PB5426XF4~com~howlin~MyApp/Documents/New%20Document%2034/StoreContent.nosync/persistentStore\n\tИспользуемый URL-адрес магазина: file://localhost/var/mobile/Applications/D423F5FF-4B8E -4C3E-B908-11824D70FD34/Documents/New%20Document%2034/StoreContent.nosync/persistentStore\n"; NSPersistentStoreUbiquitousContentNameKey = "Новый документ 34"; }
Ошибка, кажется, думает, что я создаю магазин, который уже существует при последующем открытии. Должен ли я теперь установить эту опцию iCloud в постоянном магазине при втором открытии? Я пробовал этот подход, и он тоже не сработал.
Я изучил лекции Стэнфорда по UIManagedDocument и не вижу, что я делаю неправильно.
Вот мой способ создать документ и перейти в облако:
- (void) testCreatingICloudDocWithName:(NSString*)name
{
NSURL* cloudURL = [self.docManager.iCloudURL URLByAppendingPathComponent:name isDirectory:YES];
NSURL* fileURL = [self.docManager.localURL URLByAppendingPathComponent:name];
self.aWriting = [[FNFoundationDocument alloc] initWithFileURL:fileURL];
[self setPersistentStoreOptionsInDocument:self.aWriting];
[self.aWriting saveToURL:fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
if (success == YES) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//create file coordinator
//move document to icloud
NSFileCoordinator* fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSError* coorError = nil;
[fileCoordinator coordinateWritingItemAtURL:cloudURL options:NSFileCoordinatorWritingForReplacing error:&coorError byAccessor:^(NSURL *newURL) {
if (coorError) {
NSLog(@"Coordinating writer error: %@", coorError);
}
NSFileManager* fm = [NSFileManager defaultManager];
NSError* error = nil;
NSLog(@"Before set ubiq");
[fm setUbiquitous:YES itemAtURL:fileURL destinationURL:newURL error:&error];
if (!error) {
NSLog(@"Set ubiquitous successfully.");
}
else NSLog(@"Error saving to cloud. Error: %@", error);
NSLog(@"State of Doc after error saving to cloud: %@", self.aWriting);
}];
});
}
}];
}
Вот где я устанавливаю параметры для iCloud в persistenceStore:
- (void)setPersistentStoreOptionsInDocument:(FNDocument *)theDocument
{
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[options setObject:[theDocument.fileURL lastPathComponent] forKey:NSPersistentStoreUbiquitousContentNameKey];
NSURL* coreDataLogDirectory = [self.docManager.coreDataLogsURL URLByAppendingPathComponent:[theDocument.fileURL lastPathComponent]];
NSLog(@"Core data log dir: %@", coreDataLogDirectory);
[options setObject:coreDataLogDirectory forKey:NSPersistentStoreUbiquitousContentURLKey];
theDocument.persistentStoreOptions = options;
}
И вот где я пытаюсь снова открыть его:
- (void) prepareDocForUse
{
NSURL* fileURL = self.singleDocument.fileURL;
if (![[NSFileManager defaultManager] fileExistsAtPath:[fileURL path]]) {
NSLog(@"File doesn't exist");
}
else if (self.singleDocument.documentState == UIDocumentStateClosed) {
// exists on disk, but we need to open it
[self.singleDocument openWithCompletionHandler:^(BOOL success) {
if (!success) {
NSError* error;
[self.singleDocument handleError:error userInteractionPermitted:NO];
}
[self setupFetchedResultsController];
}];
} else if (self.singleDocument.documentState == UIDocumentStateNormal) {
// already open and ready to use
[self setupFetchedResultsController];
}
}