启用NSPersistentHistoryTrackingKey后如何用NSMigrationManager完成Core Data渐进式迁移
解决方案
核心原理
你遇到的只读报错本质是迁移时打开源存储未携带NSPersistentHistoryTrackingKey配置导致的,官方文档提到的「该配置只能在容器上设置」是针对常规存储加载场景,手动迁移属于底层操作,允许直接将该配置作为参数传入迁移方法,属于官方支持的合规用法,不属于非常规 workaround。
具体实现步骤
- 先定义通用的迁移配置字典,同时包含持久化历史跟踪配置:
let commonStoreOptions: [AnyHashable: Any] = [ NSPersistentHistoryTrackingKey: true as NSNumber // 如果你同时开启了存储远程变更通知,也需要把对应的key加在这里 // NSPersistentStoreRemoteChangeNotificationPostOptionKey: true as NSNumber ]
- 修改
NSMigrationManager的调用参数,把上述配置分别传入源存储和目标存储的options参数,不要传nil:
try NSMigrationManager.migrateStore( from: currentURL, sourceType: NSSQLiteStoreType, options: commonStoreOptions, with: mappingModel, toDestinationURL: destinationURL, destinationType: NSSQLiteStoreType, destinationOptions: commonStoreOptions )
注意事项
- 源存储和目标存储都需要传入相同的配置:源存储加配置是为了绕过只读限制正常读取数据,目标存储加配置是为了自动创建历史跟踪相关表,完整迁移旧库的持久化历史记录
- 迁移执行前请先删除目标路径下的所有残留文件(包括
.sqlite、.sqlite-wal、.sqlite-shm三类文件),避免残留配置冲突 - 迁移完成后,正常加载
NSPersistentContainer时,保持NSPersistentHistoryTrackingKey配置和迁移时一致即可
验证方案
迁移完成后可以通过查询NSPersistentHistoryTransaction确认旧库的历史记录完整存在,无丢失。
内容的提问来源于stack exchange,提问作者MacMc
相关产品推荐
相关产品推荐

