此应用使用 CloudKit 在本地设备上进行记录存储和核心数据。本地创建的记录保存到 Core Data。调用以下方法将本地创建的记录发送到 CloudKit。我在应用程序启动时和应用程序从后台返回时调用此方法。我还为调用此方法的测试阶段编写了一个按钮。
行为似乎是完全随机的。例如,如果我创建 10 条记录,其中一些会正确上传到 CloudKit,而一些会失败。如果我手动重新运行该方法,最终它们都会上传到 CloudKit。我一直无法确定成功或失败的任何模式。此时,我通过一种方法播种测试记录,该方法使记录除了 recordName(UUID) 和文本字段的后缀外都相同。
通过有限的测试,如果我只创建一个记录,它总是有效。
如果我只创建两条记录,偶尔会失败。
如果我创建五个记录,几乎总是失败。
在 modifyRecordsCompletionBlock 中,无论上传是否成功,updateSavedToCloudKitSuccess() 和 cleanUpTmpFile() 总是正确完成。
我也试过增加超时,这完全没有区别。
任何指导将不胜感激。 Xcode 8.3.3 iOS10 Swift 3
func saveNewCloudKitRecordFromCoreData( myRecordName : String ) {
//get the Core Data record
let patient = findPatientRecord(myRecordName: myRecordName)
privateDatabase = container().privateCloudDatabase
sharedDatabase = sharedContainer().sharedCloudDatabase
recordZone = CKRecordZone(zoneName: "myPatientZone")
let myRecordID : CKRecordID = CKRecordID(recordName: myRecordName, zoneID: (recordZone?.zoneID)!)
let myRecord = CKRecord(recordType: "Patient", recordID : myRecordID)
myRecord.setObject(myRecordName as CKRecordValue?, forKey: "myRecordName")
myRecord.setObject(patient.firstName as CKRecordValue?, forKey: "firstname")
//bunch more fields...
let modifyRecordsOperation = CKModifyRecordsOperation(recordsToSave: [myRecord], recordIDsToDelete: nil)
modifyRecordsOperation.timeoutIntervalForRequest = 10
modifyRecordsOperation.timeoutIntervalForResource = 10
modifyRecordsOperation.modifyRecordsCompletionBlock = {
records, recordIDs, error in
if let err = error {
print("error in modifyRecordsOperation \(err.localizedDescription)")
self.updateSavedToCloudKitSuccess(recordName: myRecordName, success: false)
self.cleanUpTmpFile()
} else {
print("success in modifyRecordsOperation")
self.currentRecord = myRecord
self.updateSavedToCloudKitSuccess(recordName: myRecordName, success: true)
self.cleanUpTmpFile()
}//if err
}//modifyRecordsOperation
privateDatabase?.add(modifyRecordsOperation)
}//saveNewCloudKitRecordFromCoreData
控制台输出示例:
NOresults.count 是:7
修改记录操作成功
savedToCloudKit = true
modifyRecordsOperation 错误 修改部分记录失败
savedToCloudKit = false
modifyRecordsOperation 错误 修改部分记录失败
savedToCloudKit = false
modifyRecordsOperation 错误 修改部分记录失败
savedToCloudKit = false
modifyRecordsOperation 错误 修改部分记录失败
savedToCloudKit = false
修改记录操作成功
savedToCloudKit = true
修改记录操作成功
savedToCloudKit = true
根据 rmaddy 和 paulw11 的评论,我实现了 perRecordCompletionBlock,发现错误总是与 CKAsset 文件有关。我将查看是否在执行完成 block 之前清理了该临时文件。
每个记录完成 block :“; dateCreated = "2017-08-21 22:20:25 +0000"; dateOfBirth = "2017-04-23 22:20:25 +0000"; 名字 = 名字 12; 姓氏 = ZLastName12; myRecordName = "7621A7BD-7D32-4984-8117-2189D6F40D5F"; notes = "这是 note number12"; patientlistparent = ""; primaryPhysician = "Dr. Who12"; 桑= 123456789; }, recordType=患者>。错误:可选() modifyRecordsOperation 中的错误无法修改某些记录 savedToCloudKit = false
最佳答案
我通过将 Assets 保存操作放入同步全局队列中解决了这个问题。
DispatchQueue.global(qos: .userInitiated).sync {
let tmpDir = NSTemporaryDirectory()
let tmpFile = tmpDir.appending("test.png")
let tmpFileURL = URL(fileURLWithPath: tmpFile)
var asset : CKAsset?
if patient.conditionImage != nil {
let data = NSData(data: patient.conditionImage as! Data) as NSData
do {
try data.write(to: tmpFileURL, options: .atomic)
} catch {
print(error)
}//do catch
asset = CKAsset(fileURL: tmpFileURL)
}//if there is a conditionImage
myRecord.setObject(asset as CKRecordValue?, forKey: "conditionImage")
DispatchQueue.main.async {
//back on main
}//
}//DispatchQueue.global
关于ios - CloudKit modifyRecordsCompletionBlock 随机失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45806010/