核心数据 - 混合轻量级和自定义迁移

Eya*_*yal 19 core-data objective-c core-data-migration ios

所以我在App Store中拥有我的Core Data应用程序版本1,现在我开始处理第2版.

我对我的数据库模型进行了一些小的更改,并且我需要在完成从版本1到版本2的升级之后运行一些自定义代码.

我可以使用Core Data的轻量级迁移来处理模型更改,并且我可以在迁移完成后运行自定义代码.

问题是,我不确定将来会发生什么,当我构建版本3,4,5 ...

假设是这种情况:
版本1到版本2 - 使用轻量级迁移
版本2到版本3 - 使用模型映射
版本3到版本4的自定义迁移- 再次使用轻量级迁移
等等.

我不确定如何构建一个处理轻量级和自定义迁移混合的机制.
我在网上或在核心数据文档中找不到任何谈论这个问题的代码,我的意思是这是大多数核心数据应用程序的一个非常常见的问题,是否有针对此问题的最佳实践示例?

Pav*_*van 22

下面写了两种方法:

  1. 我个人喜欢这种方法,因为它只是天才的IMO,你可以从我的解释细节中看出为什么我对这种方法如此兴奋.这种方法已经写在Marcus Zarra的核心数据第二版中.它是重度和轻量级使用的自动渐进式迁移过程的实现.

  2. 在OP询问是否有办法避免必须为每次迁移升级使用映射模型之后,我想出了一种可能的实现方法

方法1 这是Progressive Migration的用武之地.您可以为每个版本升级创建映射模型,以便处理两个模型版本.映射模型将告诉迁移管理器如何将旧版本的数据存储映射到新版本的数据存储.因此映射模型需要a source和a destination.

然后,您需要尽可能多的映射模型,以涵盖所有版​​本升级增量.因此,如果您有4个版本,您将拥有3个映射模型,这将有助于每个版本升级之间的转换.最终你将有他们的名字命名:V1toV2MappingModel,V2to3MappingModel,V3toV4MappingModel.


然后,在每个映射模型中,您可以切换选项以使迁移管理器知道您希望如何迁移.无论是通过自定义策略还是正常的副本迁移.所以你说对于v1到v2你需要轻量级迁移,只需选择适当的映射模型,然后使用模型/映射编辑器在旧属性和新属性之间进行所需的连接/映射,如果需要自定义迁移,然后转到正确的映射模型,选择要为其自定义迁移的产品实体映射,然后在entitymapping检查器中,您将看到可以应用自定义迁移策略,只需复制迁移策略的名称即可例如,MigrationPolicyV2toV3因为您想要自定义的特定版本.

在此输入图像描述

因此,在上图中,您可以在左侧看到映射模型的名称,它是版本1到版本2.请注意,ProductToProduct实体映射的属性映射是空的 - 在中间.这是因为如果您在entity mapping检查器中查看图像的右侧Custom Policy,我会将迁移策略的名称放在其中.然后,这使迁移管理器知道(在迁移过程中)如何将属性和值从源映射到目标 - 版本1到版本2 - 并且由于输入的迁移策略,它知道这一点.这也会导致值type更改为自定义.让您知道它在ProductToProduct实体映射方面将成为自定义迁移.

然后,您必须在迁移策略中定义,该策略将决定您希望如何复制值.这是你做自定义的东西.

在此输入图像描述

从上图中可以看出,它是我为ProductToProduct实体映射设置的自定义迁移策略.你会注意到,我没有真正做任何事情的习惯,这一切都可以在没有移民政策已经完成,并可能已被简单地做通过调整几个值的副本迁移(轻量级迁移)实现entityMapping inspector和调整Attribute mapping值在之前的图像中.我只是做了所有这些迁移策略自定义的东西,只是作为一个练习,以便我可以学习并为未来做好准备只是我需要做大量迁移.现在比以后更好地学习它嘿;)

这就是做自定义的东西.我建议您阅读以下有关NSEntityMigrationPolicy的Apple开发人员参考资料以及执行更多自定义内容所需的方法,以便您知道在特定修订版升级需要某些或完全自定义迁移时如何在整个迁移过程中完全控制.


对于任何自定义/重量级迁移 - 在我的情况下,我使用一个,migration policy以便我可以在我的数据存储中从V2迁移到V3期间执行一些自定义代码 - 然后您创建一个称为"迁移策略"的东西,以便进行映射model将遵循您指定的自定义迁移规则.

您只需为每个映射模型应用所有适当的转换/映射,以便迁移管理器知道如何从一个存储升级到下一个存储.

您所需要的只是一些递归代码,它将查看现有商店的元数据,以确定它是否与最新版本兼容,如果不兼容,它将自动执行递归迁移,遵循每个规则映射模型,因为它通过版本升级,直到商店与当前版本保持同步.

因此,通过这种方式,您可以为所有用户提供任何版本,并让他们快速了解当前版本的商店.因此,如果用户处于版本1,它将递归地从V1转到V2,然后一直迁移到v3直到当前版本.如果用户具有任何其他版本,则同样适用.

这意味着在迁移过程中需要更长的时间,但无论他们拥有哪个版本,这都是迁移所有用户的好方法.

为了找到这个渐进的迁移代码,你需要阅读一本书叫Core Data 2nd Edition - Data storage and management for iOS, OS X, and iCloud,第3章Versioning and Migration子章3.6 Progressive Data Migration (An Academic Exercise)的页面54 to 59.

他通过代码与您交谈,并逐步告诉您如何编写该progressivelyMigrateURL:ofType:toModel:error:方法.一旦你和他一起编写了这个方法,他就会告诉你如何在应用程序启动时调用这个方法,这样你的用户就可以逐步自动迁移他们的商店.

所以你应该首先编写方法,然后按照上面的步骤进行操作,或者之前可以阅读子章节中的迁移策略.

在过去的48小时里,我几乎已经学会了这一切,现在就全力以赴.能够为某些版本执行轻量级迁移,然后自动完成其他版本的自定义迁移.

方法2 - 另一种解决方案虽然比较麻烦IMO:您始终可以使用轻量级迁移设置,因为您显然可以通过轻量级迁移实现复杂的情况.但是,在特定版本升级需要大量迁移的情况下,您始终可以执行if语句来检查当前存储,以及是否且仅当持久存储的当前版本与需要大量迁移的升级匹配时,然后告诉迁移管理器执行大量迁移并遵循映射模型和仅针对该实例的迁移策略,然后如果要进行更多版本升级以将持久性存储转换为最新的模型版本,则恢复轻量级迁移.

  • 我认为在谈到"轻量级迁移"时我们都有不同的含义.如果我错了,请纠正我,但你认为它只是映射模型迁移的一个简单案例,而我正在讨论轻量级和使用映射模型之间的技术差异.核心数据文档中描述的轻量级(在创建psc时仅使用两个标志),与映射模型相比具有性能优势,例如,无需将对象带入内存并复制它们.所以我希望尽可能利用这种方法,即使不需要也不要为每次迁移使用映射模型. (2认同)
  • 你可以以低于40美元的价格购买这本书的电子版,而且没有运费.好像你在这里花了更多的时间来问这个问题而不是书的价值;-) (2认同)