Що мені потрібно зробити, щоб основні дані автоматично переносити моделі?


96

Я прочитав документацію про автоматичну / полегшену міграцію для моделей Core Data, але у мене виникають проблеми з її реалізацією.

Наскільки я розумію, програма повинна помітити, що модель, яку вона має, і модель, яка вже існує на пристрої, не однакові. Якщо ви додали лише атрибути або відносини та подібні прості зміни, модель слід оновити автоматично.

Будь-які вказівники - чи потрібно щось встановлювати в Xcode?

Відповіді:


138

Зараз я з’ясував, що це досить просто - коли ти знаєш, де шукати.

У своєму AppDelegate я налаштував NSPersistentStoreCoordinator - і вам потрібно додати до нього деякі параметри, щоб сказати йому обробляти автоматичну міграцію:

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:

[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,

[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

NSError *error;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
    // Handle error
    NSLog(@"Problem with PersistentStoreCoordinator: %@",error);
}

Тоді вам потрібно зробити невелику хитрість у xCode:

  1. Виберіть файл xcdatamodel
  2. Виберіть меню дизайну у верхній частині - потім модель даних - а потім виберіть Додати модель версії
  3. Потім ваш файл xcdatamodel буде переміщено в новий каталог з тим самим іменем, що і ваш файл xcdatamodel, але з розширенням xcdatamodeld - у цьому каталозі буде другий файл з 2 у назві. Виберіть новий файл, а потім Проектування-> Модель даних-> Встановити поточну версію ( у Xcode 4 ви це робите )
  4. Якщо ви вже внесли зміни, які спричинили несумісність вашого проекту, вийміть ці зміни з оригінального файлу xcdatamodel. Якщо вам ще не потрібно внести зміни - просто відредагуйте файл 2.xcdatamodel (той, який ви щойно зробили в поточній версії).
  5. Тепер, коли ви встановлюєте цю версію на пристрій зі старою моделлю, він автоматично оновить цю модель до нової.

Це здається чудовим і таким простим, як я хотів - але я думаю, що під час зміни моделі потрібно бути обережним - інакше доведеться створювати нову версію для кожної зміни.

Я думаю, що я буду робити, це те, що я зберігатиму всі змінені файли, а потім, як тільки я буду готовий до розгортання мого оновлення, я видалю всі проміжні файли і просто розгортаю за допомогою найстаріших і найновіших моделей.


ОНОВЛЕННЯ (15.07.2011):

Дякую @ rockstarberlin за те, що він вказує, що в apple є оновлена ​​документація:

Xcode 4: Встановлення поточної версії керованої об'єктної моделі

Оновлення: 19.08.2013 краще посилання:

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmModelFormat.html


Я пропоную прочитати Посібник із міграції основних даних та керування версіями, доступний у засобі перегляду документів Xcode та на веб-сайті developer.apple.com.
Мисливець

1
Я не знайшов там просто викладеної відповіді - знадобився час, щоб дізнатись, як це зробити.
Grouchal

NSInferMappingModelAutomaticallyOption працює добре, але лише для простих відображень, наприклад, зміни назви атрибута. Для чогось більш складного (зв’язки, видалення або додавання сутностей) вам потрібно буде додати модель зіставлення. Якщо Xcode скаржиться, що NSInferMappingModelAutomaticallyOption не оголошено, додайте #import <CoreData / CoreData.h> до файлу заголовка делегата програми.
Elise van Looij

Я додав кілька сутностей до своєї моделі і отримав сумно відому помилку "Модель, яка використовується для відкриття магазину, несумісна з моделлю, яка використовується для створення магазину". Ваше рішення це виправило! Велике спасибі!
Karsten Silz

1
Дивіться відповідь Santthosh нижче, якщо ви отримуєте помилку "не можна об'єднувати моделі з двома різними об'єктами з іменем", слідуючи цим інструкціям.
benvolioT

14

Це було неймовірно корисно. Документація Apple, як завжди, була надзвичайно неповною. Я рекомендую виконати чисту збірку, оскільки під час першого запуску після внесення змін у мене трапилася помилка "Не вдається об'єднати моделі з двома різними об'єктами xxx". Чиста конструкція це виправила.


Чиста збірка також виправила мої проблеми.
jrainbow

6

Відповідь Grouchal ідеальна ... але якщо у вас все ще є "Не вдається об'єднати моделі з двома різними сутностями xxx", навіть після очищення збірки кілька разів ... Можливо, у вас виникнуть проблеми з тим, як завантажується managedObjectModel .. .погляньте на цей ... який допоміг мені це виправити ..

основні проблеми міграції даних


3

Крім того, якщо ви натрапили на цю публікацію, як і я, після отримання помилки "Модель, яка використовується для відкриття магазину, несумісна з моделлю, яка використовується для створення магазину", і ви просто налагоджуєте за допомогою симулятора і хочете повністю замінити встановлену стару модель, ви можете просто скинути додаток Симулятор, або видалення програми із симулятора, можливо, також спрацює.

Мені не спало на думку спробувати це до прочитання публікацій тут, після чого я зрозумів, що встановив додаток у симуляторі, а потім змінив модель, спричинивши згадану помилку під час виконання.


1

Щоб продовжити відповідь Санттоша, я вирішив, що замість цього я розміщу фрагмент коду тут. Вам потрібно створити ваш managedObjectModel, initWithContentsOfURL:а не mergedModelFromBundles:інакше ви отримаєте помилку:

Неможливо об’єднати моделі з двома різними об’єктами XXX та XXX

Якщо ваш файл моделі має ім'я "Модель", ось як ви створюєте ManagObjectModel:

NSString *path = [[NSBundle mainBundle] pathForResource:@"Model" ofType:@"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL]; 

Запис у цьому дописі в блозі .



1

У мене це питання роками, і я спробував усі ці відповіді безрезультатно. Сьогодні я нарешті зрозумів, що я роблю не так. Дуже проста проблема, але я її пропустив. При створенні нової версії моделі даних, якщо ви ДОДАЄТЕ стовпці, обов’язково позначте їх як НЕОБОВ’ЯЗКОВІ. Якщо ви цього не зробите, проста міграція не буде працювати, оскільки нові значення стовпців не будуть заповнені.

Як тільки я переконався, що для моїх нових стовпців встановлено позначку "необов’язково", я спробував міграцію ще раз, і вона спрацювала.


1

Я натрапив на цю публікацію через інші проблеми, але помилка полягала в " Конфігурація моделі, яка використовувалася для відкриття магазину, несумісна з тією, яка була використана для створення магазину ".

Ось моя проблема та її рішення. У своїй моделі я використовував конфігурації . У мене були деякі сутності, які зберігаються в одному файлі, а інші - у другому. (У мене є деякі за замовчуванням, які періодично потрібно завантажувати, і було б неймовірно болісно об’єднати їх у ціле). Як би там не було, я створив нову сутність. Здавалося, програма працювала нормально, але щоразу, коли я кидав, я отримував вищевказану помилку.

Рішенням було поглянути на мої конфігурації, зрозуміти, що я маю сутність, яка наразі не була в жодній з конфігурацій, і додати її до однієї. Біжить, як сон.

Це не вирішить проблему ОП. Але, можливо, якась розчарована людина, яка приземлиться сюди через Google, буде в човні, в якому я був :)


0

iOS 4.0+

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"model" withExtension:@"momd"];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

0

Незначне редагування чудових інструкцій @ Grouchal вище для Xcode версії 5:

Старий: 2. Виберіть меню дизайну вгорі - потім модель даних - потім виберіть Додати модель версії

Версія 5+: 2. Виберіть меню Редактор, потім Додати модель версії…, введіть назву вашої версії та На основі моделі (виберіть оригінальну модель зі списку)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.