如何将一个 Core Data 模型迁移到一个全新的模型?

Posted

技术标签:

【中文标题】如何将一个 Core Data 模型迁移到一个全新的模型?【英文标题】:How do I migrate one Core Data model to a completely new model? 【发布时间】:2013-10-27 10:29:30 【问题描述】:

我正在重写一个使用 Core Data 的 ios 应用程序,但是当前的对象模型已经过时,并不能真正反映当前版本的应用程序如何使用该模型。例如,有几个实体表示颜色之类的东西,我想将它们简化为单个 NSString 属性*。

我知道轻量级迁移无法应对这种情况,我不确定是否可以对当前模型进行版本化并使用手动迁移。创建一个全新的 Core Data 模型然后手动将所有现有项目迁移到新模型中会更容易吗? FWIW,通常少于 100 个项目,而且我的应用不使用 iCloud 同步,因此迁移到新模型应该相当快。

*我目前有一个具有色相、饱和度和亮度的实体,但我计划使用单个十六进制代码字符串(我现在只使用 RGB 颜色)。

【问题讨论】:

不,您不能为此方法创建新模型版本。当您实例化您的 NSManagedObjectModel 时,您将获得它的当前版本(在您的情况下,它将是具有十六进制颜色字符串属性的新模型)。如果您确实知道如何执行,我建议您执行手动迁移 - 这会更简单并且会节省大量时间,因为手动迁移是显而易见的且易于调试的过程,而使用映射模型进行迁移则不是。 【参考方案1】:

您可以创建一个新的模型版本,然后使用 NSEntityMigrationPolicy 将实体从一个模型版本转换为另一个。

定义你的新数据模型版本,填写映射模型并在Custom Policy下设置NSEntityMigrationPolicy文件。

有一个帖子 here 应该可以帮助您开始了解实体迁移政策。 他们的例子是:

- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)inSourceInstance
                                 entityMapping:(NSEntityMapping *)inMapping
      manager:(NSMigrationManager *)inManager
                                         error:(NSError **)outError


NSManagedObject *newObject;
NSEntityDescription *sourceInstanceEntity = [inSourceInstance entity];

if ( [[sourceInstanceEntity name] isEqualToString:@"Foo"] )

  newObject = [NSEntityDescription insertNewObjectForEntityForName:@"Foo"
                                                 inManagedObjectContext:[inManager destinationContext]];


  NSDictionary *keyValDict = [inSourceInstance committedValuesForKeys:nil];
  NSArray *allKeys = [[[inSourceInstance entity] attributesByName] allKeys];
  NSInteger i, max;
  max = [allKeys count];
  for (i=0 ; i< max ; i++)
  
  // Get key and value
  NSString *key = [allKeys objectAtIndex:i];
  id value = [keyValDict objectForKey:key];
  if ( [key isEqualToString:@"Bar"] )
  
    [newObject setValue:[NSNumber numberWithBool:[value boolValue]] forKey:key];
  
  else
    [newObject setValue:value forKey:key];
  



[inManager associateSourceInstance:inSourceInstance
             withDestinationInstance:newObject
                     forEntityMapping:inMapping];

return YES;

基本上你要做的是检查sourceInstance中的属性(keys),在示例中称为“Foo”。 sourceInstance 是您当前具有色相、饱和度和亮度的实体。为每个属性执行你的魔法来创建“单个十六进制代码字符串”。该字符串将成为newObjectkey 的值。

在这个post 的末尾有一个migrateIfNeeded 方法来检查是否需要转换。 (不确定您是否需要它,或者您是否已经有 isNeeded 逻辑)

【讨论】:

以上是关于如何将一个 Core Data 模型迁移到一个全新的模型?的主要内容,如果未能解决你的问题,请参考以下文章

iOS - 如何使用 Core Data 将 2 个实体迁移到 1 个?

在 Core Data 中使用数据模型迁移时应用程序崩溃

Core Data 自动迁移不会在我的新模型中创建新实体

执行 Core Data 迁移时,如何从不同实体的源存储中继承旧值?

如何将实体上的属性迁移到 Core Data 中的实体

轻量级迁移后如何从 Core Data 中删除数据