Core Data三表中两表修改未保存,疑与迁移操作相关
Core Data重启后部分数据丢失问题求助
使用Core Data存储数据,通过DB Browser for SQLite查看模拟器数据库。执行数据创建流程后,数据库中所有条目和关联正常显示,但重启应用后,FoodItem条目保留,ComposedFoodItem、Ingredient条目及关联关系全部消失。
核心数据创建函数
/** Creates a new ComposedFoodItem from the ComposedFoodItemViewModel. Creates the related FoodItem and the Ingredients. Creates all relationships. - Parameter composedFoodItemVM: The source view model. - Returns: A Core Data ComposedFoodItem; nil if there are no Ingredients. */ static func create(from composedFoodItemVM: ComposedFoodItemViewModel, generateTypicalAmounts: Bool) -> ComposedFoodItem? { debugPrint(AppDelegate.persistentContainer.persistentStoreDescriptions) // The location of the .sqlite file let moc = AppDelegate.viewContext // Create new ComposedFoodItem (1) let cdComposedFoodItem = ComposedFoodItem(context: moc) // No existing composed food item, therefore create a new UUID cdComposedFoodItem.id = UUID() // Fill data cdComposedFoodItem.amount = Int64(composedFoodItemVM.amount) cdComposedFoodItem.numberOfPortions = Int16(composedFoodItemVM.numberOfPortions) // Create the related FoodItem (2) let cdFoodItem = FoodItem.create(from: composedFoodItemVM, generateTypicalAmounts: generateTypicalAmounts) // Relate both (3) cdComposedFoodItem.foodItem = cdFoodItem // Add cdComposedFoodItem to composedFoodItemVM composedFoodItemVM.cdComposedFoodItem = cdComposedFoodItem // Save before adding Ingredients, otherwise this could lead to an NSInvalidArgumentException (4) try? moc.save() // Add new ingredients (5) if let cdIngredients = Ingredient.create(from: composedFoodItemVM) { cdComposedFoodItem.addToIngredients(NSSet(array: cdIngredients)) // Save new composed food item try? moc.save() // Return the ComposedFoodItem return cdComposedFoodItem } else { // There are no ingredients, therefore we delete it again and return nil moc.delete(cdComposedFoodItem) try? moc.save() return nil } }
执行流程
- 在
ComposedFoodItem表创建新条目
- 在
- 在
FoodItem表创建新条目
- 在
- 建立两个条目关联
- 保存修改(此时数据库可见两个新条目及正确关联)
- 在
Ingredient表创建1~n个新条目并关联到步骤1的条目
- 在
自定义迁移策略背景
近期完成了从数据模型版本1("EasyFPU")到版本2("EasyFPU 2")的Core Data迁移,针对ComposedFoodItem和Ingredient表设置了自定义迁移策略,逻辑一致:
/** No Ingredient is created in the destination model, i.e., there will be no Ingredients */ override func createDestinationInstances(forSource sourceIngredient: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws { // Do nothing on purpose debugPrint("Not migrating Ingredient with ID: \((sourceIngredient as? Ingredient)?.id.uuidString ?? "unknown")") }
怀疑迁移策略在重启时被触发,但断点未捕获到debugPrint输出,迁移本应已完成。
AppDelegate中Core Data容器配置
lazy var persistentContainer: NSPersistentCloudKitContainer = { let container = NSPersistentCloudKitContainer(name: "EasyFPU") container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { fatalError("Unresolved error \(error), \(error.userInfo)") } }) return container }()
曾尝试修改容器名从"EasyFPU"到"EasyFPU 2",但确认容器名称与模型版本无关。
请问有哪些可能的解决思路?
内容的提问来源于stack exchange,提问作者Ulrich
相关产品推荐
相关产品推荐

