Core Data自定义策略迁移:创建Store与Item的一对多关系
解决Core Data自定义迁移中Store与Item一对多关系的建立问题
核心思路
旧模型中Store的三个水果属性(apples/oranges/pineapples)需要拆分为独立的Item实体,每个Item对应一种水果,同时建立Store到Item的一对多关系。这部分无法通过映射模型自动完成,必须在自定义迁移策略中手动创建Item实例并关联。
具体步骤
1. 确认模型与映射模型配置
- 新数据模型中:
- Store实体添加
items关系,类型为to-many,目标实体为Item,勾选"Optional",删除规则设为Cascade - Item实体添加
store关系(反向关系),类型为to-one,目标实体为Store,勾选"Optional"
- Store实体添加
- 映射模型中:
- 选中Store实体的映射条目,在右侧检查器中设置
Custom Policy为你的自定义迁移策略类(比如StoreMigrationPolicy)
- 选中Store实体的映射条目,在右侧检查器中设置
2. 实现自定义迁移策略类
创建继承自NSEntityMigrationPolicy的类,重写createDestinationInstances(forSource:s:in:)方法,手动生成Item并关联到Store:
import CoreData class StoreMigrationPolicy: NSEntityMigrationPolicy { override func createDestinationInstances(forSource sInstance: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws { // 创建新的Store实例 let destinationStore = NSEntityDescription.insertNewObject(forEntityName: "Store", into: manager.destinationContext) // 迁移原Store的基础属性(如果有) if let name = sInstance.value(forKey: "name") as? String { destinationStore.setValue(name, forKey: "name") } // 遍历三种水果,创建对应的Item并关联 let fruitTypes: [(name: String, key: String)] = [ ("apples", "apples"), ("oranges", "oranges"), ("pineapples", "pineapples") ] for fruit in fruitTypes { guard let count = sInstance.value(forKey: fruit.key) as? Int16 else { continue } if count <= 0 { continue } // 可选:跳过数量为0的水果 // 创建Item实例 let item = NSEntityDescription.insertNewObject(forEntityName: "Item", into: manager.destinationContext) item.setValue(fruit.name, forKey: "name") item.setValue(count, forKey: "count") // 关联到Store的items集合 if var items = destinationStore.mutableSetValue(forKey: "items") { items.add(item) } // 手动设置反向关系(可选,Core Data通常自动维护,手动设置更可靠) item.setValue(destinationStore, forKey: "store") } // 将新Store实例关联到迁移管理器 manager.associate(sourceInstance: sInstance, withDestinationInstance: destinationStore, for: mapping) } }
3. 排查常见问题
- 确保自定义策略类的类名在映射模型中正确填写(Swift项目注意模块前缀,比如
YourAppName.StoreMigrationPolicy) - 开启Core Data调试日志查看报错:
UserDefaults.standard.set(true, forKey: "com.apple.CoreData.Logging.stderr") - 检查新模型关系配置:避免将
items误设为to-one,确认反向关系已正确关联 - 验证迁移上下文保存逻辑,捕获并打印异常信息
内容的提问来源于stack exchange,提问作者MostPalone
相关产品推荐
相关产品推荐

