Могут ли Core Data справиться с моими потребностями в переносе данных «система против пользователя»? - PullRequest
2 голосов
/ 15 июля 2010

Приложение для моего iPhone будет иметь только для чтения"системные" данные И чтение / запись"пользовательские" данные (хранятся с использованием Core Data или пользовательской базы данных SQLite). Пользовательские данные могут ссылаться на системные данные. Когда установлена ​​новая версия приложения (например, через iTunes):

  • Системные данные новые , поставляемые с обновлением, должны перезаписать / заменить старые системные данные
  • Пользовательские данные должны быть изменены для ссылки на новые системные данные (где это возможно).

Вопрос: Как этот тип миграции выполняется с Core Data? Это возможно?

Например, допустим, мое приложение предназначено для управления рецептами.

  • Каждая версия приложения поставляется с набором рецептов по умолчанию.
  • Пользователь может не редактировать эти "официальные" рецепты.
  • Однако разработчик может изменить (или удалить) любые «официальные» рецепты в будущих версиях приложения.
  • Пользователи могут добавлять примечания / комментарии к «официальным» рецептам (например, «выпекать 45 минут вместо 30»).

Когда пользователь обновляется до новой версии приложения, мы хотим сохранить комментарии пользователей и попытаться повторно связать их с соответствующими рецептами из нового, «официального» набора рецептов. Возможно ли это / осуществимо с Core Data? Или, может быть, я должен просто использовать простое решение «базы данных» (например, SQLite и традиционные операции создания / чтения / обновления / удаления)?

Спасибо!

1 Ответ

11 голосов
/ 15 июля 2010

У вас должно быть два постоянных магазина. Хранилище только для чтения, которое находится в вашем комплекте, и хранилище для чтения / записи, которое находится в каталоге документов.

Вы можете добавить оба магазина в NSPersistentStoreCoordinator и получить к ним доступ из одного NSManagedObjectContext.

Если оба хранилища имеют одну и ту же сущность, вам нужно позвонить -assignObject:toPersistentStore:, чтобы сообщить Core Data, в какое хранилище сохранить сущность. Если каждая базовая модель имеет разные сущности, то в этом нет необходимости.

Кроме того, вы можете «связать» заметки с рецептом только для чтения, убедившись, что каждый рецепт имеет уникальный идентификатор (который вы создаете), и записка хранит его, чтобы вы могли использовать извлеченное свойство для извлечения соответствующего рецепта и ассоциированные заметки.

ObjectID

Во-первых, не используйте -objectID для связи между магазинами. Он может меняться и меняется во время миграции (и в других случаях), что сделает вашу миграцию НАМНОГО ужаснее, чем нужно.

Миграция

Миграция очень проста. Если вам нужно изменить модель данных только для чтения, просто измените ее и включите новую версию в ваше приложение.

Если вам нужно изменить модель чтения-записи, создать новую модель, использовать автоматическую миграцию во время тестирования, а когда вы будете готовы к отправке, напишите NSMappingModel из старой версии в новую версию.

Поскольку два постоянных хранилища (и связанные с ними модели) не связаны, риск миграции очень мал. Единственный «улов» заключается в том, что код шаблона для Core Data не сможет автоматически разрешить исходную модель для миграции. Чтобы решить эту проблему, вам нужно немного подойти и помочь:

  1. Встаньте в пункт назначения NSPersistentStoreCoordinator и следите за ошибкой. Если вы получили ошибку миграции:
  2. Найдите исходные модели и создайте экземпляр NSManagedObjectModel со всеми соответствующими исходными моделями.
  3. Создайте экземпляр NSMigrationManager и передайте ему исходную и целевую модели
  4. Позвоните - migrateStoreFromURL: type: options: withMappingModel: toDestinationURL: destinationType: destinationOptions: error:, чтобы начать миграцию
  5. Прибыль!

Немного больше работы по переносу таким способом. Если ваши две модели сильно разделены, вы можете сделать это немного по-другому, но для этого потребуется тестирование (как и все):

  1. Отловить ошибку миграции
  2. Вставьте новый NSPersistentStoreCoordinator с просто постоянным хранилищем (и моделью), которое необходимо перенести.
  3. Пусть тот мигрирует.
  4. Снесите это NSPersistentStoreCoordinator и попытайтесь снова поднять свой основной NSPersistentStoreCoordinator.
...