CoreData 学习笔记八-CoreData 实体增加属性并支持 iCloud 同步

最近项目中需要拓展一下已经定义好的实例字段,同时原本的实例是支持l iCoud 同步的,新增加实力(Entity)字段后,我们的预期是「老版本升级上来的用户能正常使用,同时还能正常进行 iCloud 同步」,即用户对字段升级毫无感知。

这篇文章就介绍技术实现的具体细节。

这里还是用 Student 学生这个实例来举例子,原始有 age, name, school 三个属性,我们希望新增一个分数 score 的属性。

Model 配置如图,Cloud 配置是云端配置,Student 已经配置在了 Cloud 中,具体的配置流程可以参考我之前的这篇文章 CoreData+CloudKit使用流程 (opens new window)

Untitled

对于一些比较简单的情况,Core Data通常可以执行自动数据迁移,称为轻量级迁移。轻量级迁移是通过源托管对象模型与目标托管对象模型之间的差异推断出的迁移。

我上面说的这种情况(添加一个属性)就可以使用轻量级的迁移方式,具体支持轻量级迁移方式的场景可以参考官方文档 CoreData-Migrating your data model automatically (opens new window)

这篇文章目前就只介绍轻量级迁移的方式,之后如果有需要再更新手动迁移的方式。

我们在 AppDelegateNSPersistentCloudKitContainer 配置的地方,增加如下两行加粗代码

let container = NSPersistentCloudKitContainer(name: "coredata_extend")
let cloudStoreDescription = NSPersistentStoreDescription(url: self.cloudStorePath())
cloudStoreDescription.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions.init(containerIdentifier: "iCloud.com.coredata_extend")
cloudStoreDescription.configuration = "Cloud"
//新增两行代码
**cloudStoreDescription.shouldInferMappingModelAutomatically = true
cloudStoreDescription.shouldMigrateStoreAutomatically = true**
container.persistentStoreDescriptions = [ cloudStoreDescription ]

介绍一下相关的两个属性

  1. shouldInferMappingModelAutomatically **:**如果将该标志设置为YES,协调器将尝试在找不到映射模型时推断一个。该标志的默认值为YES。
  2. shouldMigrateStoreAutomatically: 这个标志位指是否应该自动迁移关联的持久化存储。如果将其设置为NO且本地存储没有和最新的数据模型同步,即两个新旧版本模型不一致,尝试加载本地存储将产生错误。如果将其设置为YES且存储不同步,尝试加载存储将导致Core Data尝试进行迁移。默认情况下,该标志设置为YES。

配置后之后,我在视图点击方法里创建一个 Student 实例,配置上 score 属性值,然后正常进行保存。

let stu = Student(context: appDelegate.persistentContainer.viewContext)
stu.name = "Liuyu"
stu.school = "WD"
stu.age = 18
stu.score = 19
try appDelegate.persistentContainer.viewContext.save()

在已经安装了旧版本 Model 的手机上,运行新代码,执行对应的实例创建方法。等一下在云端查看对应数据发现已经保存上了,如图

Untitled

同时如果老设备没有更新到带有新增属性的数据模型版本的话,也是能获取到最新的数据,并不会出现启动的时候因为属性不兼容导致的崩溃,只不过获取到的数据是没有新增属性的。

参考地址:

  1. CoreData-Migrating your data model automatically (opens new window)