CloudKit modifyRecordsCompletionBlock 随机失败
CloudKit modifyRecordsCompletionBlock Fails Randomly
此应用使用 CloudKit 在本地设备上进行记录存储和核心数据。本地创建的记录保存到 Core Data。调用以下方法将本地创建的记录发送到 CloudKit。我在应用程序启动时以及应用程序从后台 returns 调用此方法。我还为调用此方法的测试阶段编写了一个按钮。
行为似乎完全随机。例如,如果我创建 10 条记录,其中一些会正确上传到 CloudKit,而一些会失败。如果我手动重新运行该方法,最终它们都会上传到 CloudKit。我一直无法确定成功或失败的任何模式。此时,我通过一种方法播种测试记录,该方法使记录除了 recordName(UUID) 和文本字段的后缀外都相同。
通过有限的测试,如果我只创建一条记录,它总是有效。
如果我只创建两条记录,偶尔会失败。
如果我创建五个记录,几乎总是失败。
在 modifyRecordsCompletionBlock 内部,无论上传是否成功,updateSavedToCloudKitSuccess() 和 cleanUpTmpFile() 总是正确完成。
我也试过增加超时,这完全没有区别。
如有任何指导,我们将不胜感激。 Xcode8.3.3iOS10Swift3
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
修改记录操作成功
保存到CloudKit = true
modifyRecordsOperation 错误无法修改某些记录
保存到CloudKit = false
modifyRecordsOperation 错误无法修改某些记录
保存到CloudKit = false
modifyRecordsOperation 错误无法修改某些记录
保存到CloudKit = false
modifyRecordsOperation 错误无法修改某些记录
保存到CloudKit = false
修改记录操作成功
保存到CloudKit = true
修改记录操作成功
保存到CloudKit = true
根据 rmaddy 和 paulw11 的评论,我实现了 perRecordCompletionBlock,发现错误总是与 CKAsset 文件有关。我将查看是否在执行完成块之前清理了该临时文件。
每个记录完成块:“;
dateCreated = "2017-08-21 22:20:25 +0000";
dateOfBirth = "2017-04-23 22:20:25 +0000";
名字 = 名字 12;
姓氏 = ZLastName12;
myRecordName = "7621A7BD-7D32-4984-8117-2189D6F40D5F";
笔记 = "This is note number12";
patientlistparent = "";
初级医师 = "Dr. Who12";
桑= 123456789;
}, recordType=患者>。错误:可选()
modifyRecordsOperation 中的错误无法修改某些记录
saveToCloudKit = false
我通过将资产保存操作放入同步全局队列中解决了这个问题。
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
此应用使用 CloudKit 在本地设备上进行记录存储和核心数据。本地创建的记录保存到 Core Data。调用以下方法将本地创建的记录发送到 CloudKit。我在应用程序启动时以及应用程序从后台 returns 调用此方法。我还为调用此方法的测试阶段编写了一个按钮。
行为似乎完全随机。例如,如果我创建 10 条记录,其中一些会正确上传到 CloudKit,而一些会失败。如果我手动重新运行该方法,最终它们都会上传到 CloudKit。我一直无法确定成功或失败的任何模式。此时,我通过一种方法播种测试记录,该方法使记录除了 recordName(UUID) 和文本字段的后缀外都相同。
通过有限的测试,如果我只创建一条记录,它总是有效。
如果我只创建两条记录,偶尔会失败。
如果我创建五个记录,几乎总是失败。
在 modifyRecordsCompletionBlock 内部,无论上传是否成功,updateSavedToCloudKitSuccess() 和 cleanUpTmpFile() 总是正确完成。
我也试过增加超时,这完全没有区别。
如有任何指导,我们将不胜感激。 Xcode8.3.3iOS10Swift3
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
修改记录操作成功
保存到CloudKit = true
modifyRecordsOperation 错误无法修改某些记录
保存到CloudKit = false
modifyRecordsOperation 错误无法修改某些记录
保存到CloudKit = false
modifyRecordsOperation 错误无法修改某些记录
保存到CloudKit = false
modifyRecordsOperation 错误无法修改某些记录
保存到CloudKit = false
修改记录操作成功
保存到CloudKit = true
修改记录操作成功
保存到CloudKit = true
根据 rmaddy 和 paulw11 的评论,我实现了 perRecordCompletionBlock,发现错误总是与 CKAsset 文件有关。我将查看是否在执行完成块之前清理了该临时文件。
每个记录完成块:“; dateCreated = "2017-08-21 22:20:25 +0000"; dateOfBirth = "2017-04-23 22:20:25 +0000"; 名字 = 名字 12; 姓氏 = ZLastName12; myRecordName = "7621A7BD-7D32-4984-8117-2189D6F40D5F"; 笔记 = "This is note number12"; patientlistparent = ""; 初级医师 = "Dr. Who12"; 桑= 123456789; }, recordType=患者>。错误:可选() modifyRecordsOperation 中的错误无法修改某些记录 saveToCloudKit = false
我通过将资产保存操作放入同步全局队列中解决了这个问题。
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