Cloud Kit数据存在性校验失败致多设备重复导入问题排查
问题:Core Data同步Cloud Kit时重复导入数据
我的App首次启动会执行数据导入操作,已配置将Core Data存储至Cloud Kit。当前问题:一台设备导入正常,但第二台设备运行时会重复导入,造成记录重复。我尝试在导入前校验Cloud Kit中是否存在数据,但即便确认已有记录,校验结果始终返回false。
校验调用代码
NSLog("Existance Check") checkIfExistsInCloudKit() { (result) in print(result) if result == false { NSLog("Does Not Exist") //let ImportData : ImportData = ImportData(viewContext: viewContext) //ImportData.importAll() } else { NSLog("Does Exist") } } NSLog("Existance Check Complete")
校验函数代码
func checkIfExistsInCloudKit(_ completion: @escaping (Bool) -> ()) { var result = false let container = CKContainer(identifier: "******") let privateDB = container.privateCloudDatabase let predicate = NSPredicate(format: "CD_brand = %@", "DMC") let query = CKQuery(recordType: "CD_Colour", predicate: predicate) privateDB.perform(query, inZoneWith: nil) { records, error in //guard let records = records else { return } result = true } completion(result) }
打印结果
2023-04-15 14:07:28.092262+0100 Stitchers Companion[4553:113693] Existance Check
false
2023-04-15 14:07:28.092897+0100 Stitchers Companion[4553:113693] Does Not Exist
2023-04-15 14:07:28.092962+0100 Stitchers Companion[4553:113693] Existance Check Complete
问题原因
privateDB.perform(query...)是异步操作,你在调用它之后立刻执行了completion(result),此时异步请求还未完成,result还是初始值false,所以不管Cloud Kit里有没有数据,都会先返回false。另外,异步回调里直接把result设为true,既没判断查询结果是否真的存在记录,也没处理错误情况,逻辑存在漏洞。
修复后的校验函数
func checkIfExistsInCloudKit(_ completion: @escaping (Bool) -> ()) { let container = CKContainer(identifier: "******") let privateDB = container.privateCloudDatabase let predicate = NSPredicate(format: "CD_brand = %@", "DMC") let query = CKQuery(recordType: "CD_Colour", predicate: predicate) // 等待异步查询完成后再执行回调 privateDB.perform(query, inZoneWith: nil) { records, error in if let error = error { print("查询Cloud Kit出错: \(error)") completion(false) return } // 判断查询结果是否包含有效记录 let exists = records?.isEmpty == false completion(exists) } }
额外优化建议
- 可以在Cloud Kit中单独存储一个「导入标记」记录(比如创建
ImportMarker类型,包含isDataImported字段),首次导入成功后创建该标记,后续启动只需检查这个标记是否存在,比查询大量数据更高效。 - 确保两台设备使用同一个iCloud账户,否则私有数据库的数据不会跨设备同步。
内容的提问来源于stack exchange,提问作者Ceri Turner
相关产品推荐
相关产品推荐

