我正在为一个新应用程序开发 PoC,但我遇到了两个 CoreData 实体的问题InboxItem
and CardSet
,它们中的每一个都具有可选的“对一”关系。当我在模拟器中启动应用程序并创建这些实体时,模拟器数据库和 CloudKit 仪表板中的一切看起来都很好,即两个关系都已设置。但是,当我随后在 iPhone 上运行该应用程序并等待这些新记录同步并随后访问关系时,会出现错误,说明以下关系:InboxItem
to CardSet
was nil
。看来这种关系没有正确同步“下游”(从 CloudKit 到 CoreData/iCloud 到设备)。
当 CoreData 通过 CloudKit 导入最近的更改时,日志控制台显示以下与缺失关系相关的调试输出:
Importing updated records:
(
"<CKRecord: 0x7faf0d820ac0; recordType=CD_Card, recordID=89A3FE22-1CC4-447D-BFF0-515E80933551:(com.apple.coredata.cloudkit.zone:__defaultOwner__), recordChangeTag=5, values={\n \"CD_cardSet_\" = \"5EED257A-8EF8-4749-93EF-CE2882F52C0C\";\n \"CD_entityName\" = Card;\n \"CD_id_\" = \"5F2FB4B7-A236-48F5-B2F9-FC2520C29765\";\n \"CD_language_\" = \"\\Ud83c\\Udde9\\Ud83c\\Uddea\";\n \"CD_line1_\" = \"\";\n \"CD_line2_\" = \"\";\n \"CD_line3_\" = \"\";\n}>",
"<CKRecord: 0x7faf0d822260; recordType=CD_CardSet, recordID=5EED257A-8EF8-4749-93EF-CE2882F52C0C:(com.apple.coredata.cloudkit.zone:__defaultOwner__), recordChangeTag=4, values={\n \"CD_entityName\" = CardSet;\n \"CD_id_\" = \"E4460BCE-CB08-4DDA-8DDC-1BCC23649A91\";\n \"CD_inboxItem_\" = \"212D86EC-635E-4903-BF51-85B0F36C401B\";\n}>",
"<CKRecord: 0x7faf0d815830; recordType=CD_InboxItem, recordID=212D86EC-635E-4903-BF51-85B0F36C401B:(com.apple.coredata.cloudkit.zone:__defaultOwner__), recordChangeTag=3, values={\n \"CD_addedOn_\" = \"2022-02-21 19:44:51 +0000\";\n \"CD_capturedText_\" = \"Simulator 1\";\n \"CD_cardSet_\" = \"5EED257A-8EF8-4749-93EF-CE2882F52C0C\";\n \"CD_entityName\" = InboxItem;\n \"CD_id_\" = \"68FA5FB8-2752-4E14-AA4C-C82F20215678\";\n}>",
"<CKRecord: 0x7faf0db06280; recordType=CD_Card, recordID=64324445-8E07-4D20-8212-2491E564530D:(com.apple.coredata.cloudkit.zone:__defaultOwner__), recordChangeTag=6, values={\n \"CD_cardSet_\" = \"5EED257A-8EF8-4749-93EF-CE2882F52C0C\";\n \"CD_entityName\" = Card;\n \"CD_id_\" = \"786AED19-F00C-4694-8978-897FA34E81F9\";\n \"CD_language_\" = \"\\Ud83c\\Uddec\\Ud83c\\Udde7\";\n \"CD_line1_\" = \"\";\n \"CD_line2_\" = \"\";\n \"CD_line3_\" = \"\";\n}>"
)
Deleted RecordIDs:
{
}
CoreData: debug: CoreData+CloudKit: -[PFCloudKitSerializer updateAttributes:andRelationships:onManagedObject:fromRecord:withRecordMetadata:importContext:error:](1460): Adding mirrored relationship to link for record <CKRecordID: 0x600002e5e3a0; recordName=89A3FE22-1CC4-447D-BFF0-515E80933551, zoneID=com.apple.coredata.cloudkit.zone:__defaultOwner__> related to 5EED257A-8EF8-4749-93EF-CE2882F52C0C by cardSet_
CoreData: debug: CoreData+CloudKit: -[PFCloudKitSerializer updateAttributes:andRelationships:onManagedObject:fromRecord:withRecordMetadata:importContext:error:](1460): Adding mirrored relationship to link for record <CKRecordID: 0x600002e5ebc0; recordName=5EED257A-8EF8-4749-93EF-CE2882F52C0C, zoneID=com.apple.coredata.cloudkit.zone:__defaultOwner__> related to 212D86EC-635E-4903-BF51-85B0F36C401B by inboxItem_
CoreData: debug: CoreData+CloudKit: -[PFCloudKitSerializer updateAttributes:andRelationships:onManagedObject:fromRecord:withRecordMetadata:importContext:error:](1460): Adding mirrored relationship to link for record <CKRecordID: 0x600002e41d00; recordName=212D86EC-635E-4903-BF51-85B0F36C401B, zoneID=com.apple.coredata.cloudkit.zone:__defaultOwner__> related to 5EED257A-8EF8-4749-93EF-CE2882F52C0C by cardSet_
CoreData: debug: CoreData+CloudKit: -[PFCloudKitSerializer updateAttributes:andRelationships:onManagedObject:fromRecord:withRecordMetadata:importContext:error:](1460): Adding mirrored relationship to link for record <CKRecordID: 0x600002e42180; recordName=64324445-8E07-4D20-8212-2491E564530D, zoneID=com.apple.coredata.cloudkit.zone:__defaultOwner__> related to 5EED257A-8EF8-4749-93EF-CE2882F52C0C by cardSet_
CoreData: debug: CoreData+CloudKit: -[NSCloudKitMirroringDelegate managedObjectContextSaved:](2504): <NSCloudKitMirroringDelegate: 0x6000015d0dd0>: Observed context save: <NSPersistentStoreCoordinator: 0x6000005c9c00> - <NSManagedObjectContext: 0x600001584a90>
有问题的收件箱项目是具有记录 ID 的收件箱项目212D86EC-635E-4903-BF51-85B0F36C401B
(上面更新的记录的第三个)。也就是说,它显然是导入的,并且也创建了关系(请参阅根据Adding mirrored relationship to link for record
声明)。
更新1:似乎是一个计时问题: NSFetchRequestResult.controllerDidChangeContent (我当前执行引发上述错误的检查)似乎被调用得太早 - 即在 CoreData/Coudkit 同步完成之前 - 特别是在建立关系之前。如果我在执行检查之前等待 5 秒,则不会发生错误...同时调试日志显示
CoreData: debug: CoreData+CloudKit: -[PFMirroredOneToManyRelationship updateRelationshipValueUsingImportContext:andManagedObjectContext:error:](440): Linking object with record name <CKRecordID: 0x600001a8a9e0; recordName=212D86EC-635E-4903-BF51-85B0F36C401B, zoneID=com.apple.coredata.cloudkit.zone:__defaultOwner__> to <CKRecordID: 0x600001a8a740; recordName=5EED257A-8EF8-4749-93EF-CE2882F52C0C, zoneID=com.apple.coredata.cloudkit.zone:__defaultOwner__> via cardSet_
有什么想法如何避免这种情况吗?当我第一次开始研究这个问题时(几个月前),它成功了。从那以后我没有改变任何事情。也许随着 iOS 15 的推出,行为发生了变化?
更新2:使用 iOS 14.5 运行模拟器时不会出现此问题,因此该行为已在 iOS 15.0 和 iOS 15.2 之间的某个位置引入(我将在稍后详细检查)。问题是,这是有意还是无意的行为?从我的角度来看,实体和关系现在是在单独的步骤中更新的(上下文被保存两次),这同时导致了不一致的状态。还有其他人遇到过这样的问题吗?
更新3:从 iOS 15.0 开始出现此问题。