Первичная миграция данных атрибута из String в Integer 16

У меня возникли проблемы с переносом атрибута сущности магазина из String в Integer 16. Ниже приведены шаги, которые я предпринимаю:

  • Добавить версию модели...
  • В новой модели измените атрибут Entity от String до Int 16.
  • Выберите новую модель в File Inspector > Versioned Core Data Model > Current Model
  • Создайте модель сопоставления для старых и новых моделей.
  • Run

Вот ошибка:

Неразрешенная ошибка Error Domain = NSCocoaErrorDomain Code = 134140 "операция не может быть завершена. (Cocoa ошибка 134140.)" UserInfo = 0xbd5cd20 {reason = Не удается найти или автоматически вывести сопоставление модель для миграции, destinationModel =...

Модель сопоставления находится в скомпилированном .app:

Bundle

и в проекте:

enter image description here

Миграция работает для таких атрибутов, как Integer 16 > Integer 32, или при изменении имен атрибутов.

Я попытался создать простой проект Core Data, и миграция работала автоматически (с моделью отображения и без него) от String до Integer 16 и обратно.

Самая странная часть - я пробовал искать программно для всех моделей сопоставления в комплекте, и ни одна из них не найдена для текущих исходных/целевых моделей.

Ответы

Ответ 1

Это происходит потому, что Core Data не может автоматически перенести ваш атрибут. Это связано с тем, что он не может гарантировать, что строка всегда будет соответствовать int (даже если вы знаете, что ваши данные).

Итак, вам нужно использовать модель сопоставления. Вот как это сделать:

  • В Xcode создайте новую модель сопоставления (File > New > New File), выберите Mapping Model в разделе Core Data.
  • Выберите исходный и целевой модели в мастере
  • Это в основном помещает вас в то же самое место, что и облегченная миграция, все делается автоматически, за исключением того, что вы можете переопределить какое-либо сопоставление. В частности, тот, который дает вам неприятности.
  • Создайте новый класс политики сопоставления (Extend NSEntityMigrationPolicy)
  • Внедрите createDestinationInstancesForSourceInstance:entityMapping:manager:error:, который даст вам исходный экземпляр, чтобы вы могли преобразовать эту строку в int и сохранить ее в новом хранилище.

Ваш код должен выглядеть примерно так:

- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error
{
    NSManagedObject *newObject = [NSEntityDescription insertNewObjectForEntityForName:[mapping destinationEntityName] inManagedObjectContext:[manager destinationContext]];  

    // Copy all the values from sInstance into newObject, making sure to apply the conversion for the string to int when appropriate. So you should have one of these for each attribute:
    [newObject setValue:[sInstance valueForKey:@"xyz"] forKey:@"xyz"];

    [manager associateSourceInstance:sInstance withDestinationInstance:newObject forEntityMapping:mapping];
}
  • Тогда все, что вам нужно сделать, это установить эту политику в модели сопоставления. Выберите файл модели сопоставления, выберите соответствующее сопоставление объектов и установите CustomPolicy на правой панели.

Обязательно измените параметры миграции, чтобы удалить автоматический вывод типа, где бы вы ни запускали Core Data​​p >

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, nil];

Это должно быть...

Ответ 2

Для тех, кто бросил тысячи копий на ошибку "Не удается найти модель сопоставления для миграции", это может помочь:

  • Убедитесь, что вы создали файл сопоставления в соответствующей папке/группе (перед нажатием Cmd + N - выберите .xcdatamodeld файл в навигаторе проекта).
  • Очистите проект.
  • Восстановите проект и запустите.

В моем случае приложение автоматически обнаружило модель отображения после clean/rebuild =\