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

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

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

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

【问题讨论】:

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

标签: ios objective-c core-data


【解决方案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 逻辑)

【讨论】:

    猜你喜欢
    • 2011-12-14
    • 2010-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 2010-11-18
    • 2017-10-24
    • 1970-01-01
    相关资源
    最近更新 更多