核心数据从String迁移到Integer 16

Vic*_*dan 17 core-data ios

我在将商店实体属性从String迁移到Integer 16时遇到了问题.以下是我采取的步骤:

  1. 添加模型版本......
  2. 在新模型中,将Entity属性从String更改为Int 16.
  3. 在文件检查器>版本化核心数据模型>当前模型中选择新模型
  4. 为旧模型和新模型创建映射模型.

这是错误:

未解决的错误Error Domain = NSCocoaErrorDomain Code = 134140"操作无法完成.(Cocoa错误134140.)"UserInfo = 0xbd5cd20 {reason =无法找到或自动推断迁移的映射模型,destinationModel = ...

映射模型存在于已编译的.app中:

束

在项目中:

在此输入图像描述

迁移适用于Integer 16> Integer 32等属性,或更改属性名称时.

我尝试创建一个简单的核心数据项目,并且从String到Integer 16自动迁移(有和没有映射模型).

最奇怪的部分是我尝试以编程方式查找捆绑中的所有映射模型,但没有找到当前源/目标模型.

mpr*_*vat 22

发生这种情况是因为Core Data无法自动迁移您的属性.这是因为它无法保证字符串始终适合int(即使您知道数据有效).

所以你需要做的是使用映射模型.这是怎么做的:

  1. 在Xcode中,创建一个新的映射模型(File> New> New File),在Core Data部分中选择Mapping Model
  2. 在向导中选择源模型和目标模型
  3. 这基本上使您与轻量级迁移处于同一位置,一切都是自动完成的,除了您可以选择覆盖一些映射.特别是那个给你烦恼的那个.
  4. 创建新的映射策略类(Extend NSEntityMigrationPolicy)
  5. 实现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];
}
Run Code Online (Sandbox Code Playgroud)
  1. 然后,您所要做的就是在映射模型中设置该策略.选择映射模型文件,选择适当的实体映射并在右侧面板上设置CustomPolicy.

确保更改迁移设置以在初始化Core Data的任何位置删除自动类型推断

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, nil];
Run Code Online (Sandbox Code Playgroud)

那应该是......