此应用程序使用CloudKit在本地设备上存储记录和核心数据。本地创建的记录保存到核心数据。调用以下方法将在本地创建的记录发送到CloudKit。我在应用程序启动和从后台返回时调用此方法。我还为调用此方法的测试阶段编程了一个按钮。
这种行为似乎完全是随机的。例如,如果我创建10条记录,其中一些记录会正确上载到CloudKit,而另一些记录则会失败。如果我手动重新运行该方法,最终它们都会上传到CloudKit。我一直无法确定成功或失败的模式。在这一点上,我从一个方法种子测试记录,该方法使记录完全相同,除了recordName(UUID)和文本字段的后缀。
有限的测试,如果我只创建一个记录,它总是有效的。
如果我只创造了两张唱片,那就是偶尔的失败。
如果我创造了五张唱片,几乎总是失败的。
在modifyRecordsCompletionBlock中,无论上载是否成功,updateSaveToCloudKitSuccess()和cleanUpTmpFile()始终正确完成。
我也试着增加超时时间,这完全没有区别。
任何指导都将不胜感激。Xcode 8.3.3 iOS10斯威夫特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=真
modifyRecordsOperation中的错误未能修改某些记录
savedToCloudKit=假
modifyRecordsOperation中的错误未能修改某些记录
savedToCloudKit=假
modifyRecordsOperation中的错误未能修改某些记录
savedToCloudKit=假
modifyRecordsOperation中的错误未能修改某些记录
savedToCloudKit=假
修改记录操作成功
savedToCloudKit=真
修改记录操作成功
savedToCloudKit=真
根据rmaddy和paulw11的评论,我实现了perRecordCompletionBlock,发现错误总是与CKAsset文件有关。我将查看是否在完成块执行之前清除了该临时文件。
perRecordCompletionBlock:“;
dateCreated=“2017-08-21 22:20:25+0000”;
出生日期=“2017-04-23 22:20:25+0000”;
firstname=FirstName12;
姓氏=ZLastName12;
myRecordName=“7621A7BD-7D32-4984-8117-2189D6F40D5F”;
notes=“这是便笺号码12”;
patientlistparent=“;
PrimaryMedical=“Who12医生”;
ssan=123456789;
},记录类型=患者>。错误:可选()
modifyRecordsOperation中的错误未能修改某些记录
savedToCloudKit=假
最佳答案
我通过将资产保存操作放在同步全局队列中解决了这个问题。
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