NSPersistentStoreCoordinator не создан в UIManagedDocument

Я начинаю узнавать о UIManagedDocument и его возможностях. Насколько я понимаю, это форма базы данных, хранящаяся в каталоге документов.

В любом случае, я пытаюсь использовать его в качестве базы данных, сохраняя данные в его NSManagedObjectContext, однако через несколько секунд после создания UIManagedDocument и сохранения данных в его контексте (после того, как я предполагаю, что время истекло), приложение падает, и оно говорит мне, что нет постоянного координатора магазина.

Кажется, в документах Apple не так много указаний о том, как создать постоянный координатор хранилища после создания управляемого документа.

Как мне это сделать?

Спасибо!

Изменить

Код, который я использую:

NSURL *url = [[self iCloudDocumentsURL] URLByAppendingPathComponent:nameOfDocument];

NSMutableArray *books = [self.books mutableCopy];
[books addObject:url];

[self setBooks:books];

UIManagedDocument *document = [[UIManagedDocument alloc] initWithFileURL:url];

NSDictionary *options = @{ NSMigratePersistentStoresAutomaticallyOption : @YES,
                           NSInferMappingModelAutomaticallyOption : @YES,
                           NSPersistentStoreUbiquitousContentNameKey : document.fileURL.lastPathComponent,
                           NSPersistentStoreUbiquitousContentURLKey : [self iCloudCoreDataLogFilesURL] };
[document setPersistentStoreOptions:options];

if (document.documentState == UIDocumentStateClosed) {
    [document openWithCompletionHandler:^(BOOL success) {
        Book *book = [Book newBookWithTitle:bookTitle
                     inManagedObjectContext:document.managedObjectContext];

        [document updateChangeCount:UIDocumentChangeDone];
    }];
}

Обновить

После выполнения этого кода в фоновом потоке. Мое приложение по-прежнему регистрирует «НЕТ» в случае успеха обработчика завершения после открытия документа. Однако мое приложение не падает, вместо этого я получаю следующий журнал:

2013-04-23 00:01:08.381 Notable[193:4b0b] -[_PFUbiquityRecordsImporter rollResponseOperation:encounteredAnError:whileTryingToAdoptBaseline:](1545): CoreData: Ubiquity:  <PFUbiquityBaselineRollResponseOperation: 0x1fa561d0> localPeerID: mobile.2DDB96C5-A317-5BE5-8F29-9F5E6681A27A, storeName: A-B893A0AB-B764-42F1-9402-38790DCEF96B, modelVersionHash: NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=
    ubiquityRootLocation: <PFUbiquityLocation: 0x1e59b790>: /private/var/mobile/Library/Mobile Documents/my~app~identifier/Logs

Encountered an error while trying to respond to the roll of baseline: <PFUbiquityBaseline: 0x1e54deb0>(0)
    permanentLocation: <PFUbiquityLocation: 0x1f8e7120>: /private/var/mobile/Library/Mobile Documents/my~app~identifier/Logs/.baseline/A-B893A0AB-B764-42F1-9402-38790DCEF96B/NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=/baseline.zip
    safeLocation: <PFUbiquityLocation: 0x1f8eb1b0>: /private/var/mobile/Library/Mobile Documents/my~app~identifier/Logs/.baseline/A-B893A0AB-B764-42F1-9402-38790DCEF96B/NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=/mobile.2DDB96C5-A317-5BE5-8F29-9F5E6681A27A
    currentLocation: <PFUbiquityLocation: 0x1f8e7120>: /private/var/mobile/Library/Mobile Documents/my~app~identifier/Logs/.baseline/A-B893A0AB-B764-42F1-9402-38790DCEF96B/NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=/baseline.zip

    storeName: A-B893A0AB-B764-42F1-9402-38790DCEF96B
    modelVersionHash: NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=
    baselineArchiveLocation: <PFUbiquityLocation: 0x1f8e7120>: /private/var/mobile/Library/Mobile Documents/my~app~identifier/Logs/.baseline/A-B893A0AB-B764-42F1-9402-38790DCEF96B/NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=/baseline.zip

Error: Error Domain=NSCocoaErrorDomain Code=134310 "The operation couldn’t be completed. (Cocoa error 134310.)" UserInfo=0x1f8d2ae0 {baseline=<PFUbiquityBaseline: 0x1e54deb0>(0)
    permanentLocation: <PFUbiquityLocation: 0x1f8e7120>: /private/var/mobile/Library/Mobile Documents/my~app~identifier/Logs/.baseline/A-B893A0AB-B764-42F1-9402-38790DCEF96B/NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=/baseline.zip
    safeLocation: <PFUbiquityLocation: 0x1f8eb1b0>: /private/var/mobile/Library/Mobile Documents/my~app~identifier/Logs/.baseline/A-B893A0AB-B764-42F1-9402-38790DCEF96B/NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=/mobile.2DDB96C5-A317-5BE5-8F29-9F5E6681A27A
    currentLocation: <PFUbiquityLocation: 0x1f8e7120>: /private/var/mobile/Library/Mobile Documents/my~app~identifier/Logs/.baseline/A-B893A0AB-B764-42F1-9402-38790DCEF96B/NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=/baseline.zip

    storeName: A-B893A0AB-B764-42F1-9402-38790DCEF96B
    modelVersionHash: NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=
    baselineArchiveLocation: <PFUbiquityLocation: 0x1f8e7120>: /private/var/mobile/Library/Mobile Documents/my~app~identifier/Logs/.baseline/A-B893A0AB-B764-42F1-9402-38790DCEF96B/NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=/baseline.zip
, localStoreKV=<PFUbiquityKnowledgeVector: 0x1f8220c0> ()}
userInfo: {
    baseline = "<PFUbiquityBaseline: 0x1e54deb0>(0)\n\tpermanentLocation: <PFUbiquityLocation: 0x1f8e7120>: /private/var/mobile/Library/Mobile Documents/my~app~identifier/Logs/.baseline/A-B893A0AB-B764-42F1-9402-38790DCEF96B/NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=/baseline.zip\n\tsafeLocation: <PFUbiquityLocation: 0x1f8eb1b0>: /private/var/mobile/Library/Mobile Documents/my~app~identifier/Logs/.baseline/A-B893A0AB-B764-42F1-9402-38790DCEF96B/NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=/mobile.2DDB96C5-A317-5BE5-8F29-9F5E6681A27A\n\tcurrentLocation: <PFUbiquityLocation: 0x1f8e7120>: /private/var/mobile/Library/Mobile Documents/my~app~identifier/Logs/.baseline/A-B893A0AB-B764-42F1-9402-38790DCEF96B/NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=/baseline.zip\n\n\tstoreName: A-B893A0AB-B764-42F1-9402-38790DCEF96B\n\tmodelVersionHash: NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=\n\tbaselineArchiveLocation: <PFUbiquityLocation: 0x1f8e7120>: /private/var/mobile/Library/Mobile Documents/my~app~identifier/Logs/.baseline/A-B893A0AB-B764-42F1-9402-38790DCEF96B/NK3BysbustJxxyi2O8bX8eof15YimkUnegxqX6HDkas=/baseline.zip\n";
    localStoreKV = "<PFUbiquityKnowledgeVector: 0x1f8220c0> ()";
}

Этот метод также создает «DocumentMetaData.plist» (который, как я считаю, необходим в соответствии с упоминанием этих файлов в видео CS193P, которое я упомянул в комментарии) вместо файла с названием «persistentStore».


person Adam Carter    schedule 22.04.2013    source источник
comment
Общее замечание о Core Data: если вы думаете о нем как о базе данных, в долгосрочной перспективе вы пострадаете. Core Data — это структура постоянства, а НЕ база данных. В некоторой степени он будет действовать как база данных, но есть тонкие отличия, которые будут кусать вас сзади, если вы подойдете к нему с точки зрения Core Data == базы данных.   -  person theMikeSwan    schedule 23.04.2013
comment
Да, я понимаю, что Core Data — это не база данных (как я уже сказал выше), мне просто было проще думать о UIManagedDocument как о базе данных (в любом случае для приложения, которое я создаю).   -  person Adam Carter    schedule 23.04.2013
comment
Не беспокойтесь, я просто хотел удержать вас от того, чтобы пойти по пути, который я видел, как многие другие идут по пути, а затем ненавидят жизнь в будущем.   -  person theMikeSwan    schedule 23.04.2013
comment
Да, это проблема, с которой я впервые столкнулся, когда начал работать с Core Data, я полагаю, это то, к чему люди привыкли (особенно, поскольку я пришел из MySQL/PHP).   -  person Adam Carter    schedule 23.04.2013


Ответы (3)


Вы не должны создавать его самостоятельно при использовании UIManagedDocument - это происходит за вас. Однако на практике это не так надежно. Внутри UIManagedDocument настраивает постоянное хранилище и координатора постоянного хранилища. Но этого не произойдет, пока базовый код iCloud не завершит свою работу, пообщается с сервером, загрузит любые новые данные и т. д. Тем временем вы не сможете сохранить изменения, потому что до этого процесс завершается, эти изменения негде сохранить.

Кроме того, иногда iCloud не может собраться вместе без причины, которая находится под вашим контролем.

Вероятно, вам нужно проверить значение success в вашем обработчике завершения открытия. Если это NO, вы застряли. Когда iCloud выходит из строя, пути восстановления нет, кроме как иногда, если вам повезет, вы можете просто повторить попытку несколько раз, пока это не сработает. Файловые ошибки, пожалуйста, нам нужна Apple, чтобы исправить это.

person Tom Harrington    schedule 22.04.2013
comment
Спасибо, сейчас попробую. Чего я не могу понять, так это того, насколько сложно разработчикам понять/успешно использовать iCloud. Особенно то, как Apple может «идеально» использовать это в своих приложениях. Вы могли бы подумать, что будет намного больше документации и помощи о том, как настроить iCloud и заставить его работать, поскольку ему почти 2 года. - person Adam Carter; 23.04.2013
comment
Как вы упомянули (и я не знаю, почему я не подумал об этом параметре), но успех регистрируется как НЕТ - person Adam Carter; 23.04.2013
comment
Apple вообще почти не использует iCloud с Core Data. Документы в iCloud, но без Core Data, более надежны, но далеко не идеальны, даже в приложениях Apple. - person Tom Harrington; 23.04.2013

Не уверен, что вы когда-либо исправляли этого Адама, но ваш постоянный магазин не должен быть в облаке. Всегда создавайте uiManagedDocument в локальном хранилище и просто устанавливайте параметры iCloud для addPersistentStore. CoreData предоставит вашему приложению немедленное хранилище для использования во время создания реальной версии и получения любых данных из iCloud, если таковые имеются. После этого вы переключитесь на подключенный магазин ICloud, который также является локальным. В iCloud публикуются только журналы транзакций, но это делается для вас скрыто.

person Duncan Groenewald    schedule 07.10.2013

Пример кода есть в справочнике по классам UIDocument, а также в Руководство по программированию основных данных. Вы также можете увидеть пример настройки стека Core Data, создав проект на основе Core Data с использованием шаблона Master-Detail.

Если это ваш первый опыт работы с Core Data, я предлагаю вам изучить одну из книг на эту тему: Core Data for iOS Тима Истеда и Тома Харрингтона или Core Data ( 2-е издание): Хранение данных и управление ими для iOS, OS X и iCloud, Маркус Зарра.

Я вижу пару вещей, которые выглядят странно:

  • Указывает ли [self iCloudDocumentsURL] на локальную файловую систему?

  • Почему URL-адрес вставляется в массив книг?

  • Проверьте переменную success в своем блоке, прежде чем предположить, что открытие прошло успешно.

Даже в iOS 6.x iCloud Core Data не готов к работе в прайм-тайм. Это определенно не то, чем новый разработчик iOS хочет заниматься. Посмотрите, что очень умные люди из Black Pixel сказали об этом в отношении одного из своих продуктов: http://blackpixel.com/blog/2013/03/the-return-of-netnewswire.html.

person Hal Mueller    schedule 22.04.2013
comment
Привет, спасибо за ответ. До сих пор я дошел до того, что создал приложение, похожее на то, что можно найти в видео Стэнфорда CS193P «iCloud». За исключением того, что вместо использования данных Flickr я хочу добавить свои собственные данные в контекст после создания документа. - person Adam Carter; 23.04.2013
comment
Я также использовал метод save: документов manageObjectContext вместо [document updateChangeCount:UIDocumentChangeDone];. - person Adam Carter; 23.04.2013
comment
[self iCloudDocumentsURL] по сути [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil] URLByAppendingPathComponent:@"Documents"]. Сначала это меня смутило, но это работает, когда icloud доступен и нет. Документы хранятся локально и передаются в облако (я проверял на developer.icloud.com). Массив документов используется моим представлением коллекции. Этот массив, когда он установлен, вызывает перезагрузку представления коллекции. - person Adam Carter; 23.04.2013
comment
Кроме того, когда я проверяю облако, есть структура папок «Документы» › «StoreContent», которая содержит файл «persistentStore». - person Adam Carter; 23.04.2013