ios - CloudKit modifyRecordsCompletionBlock 随机失败

标签 ios swift cloudkit

此应用使用 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/

相关文章:

ios - UIScrollView 内的 UITableView 高度错误

swift - 将对象传递出响应处理程序

ios - CloudKit 查询出现奇怪错误

iOS - 重用 EAAccessory 对象重新连接?

ios - SwiftUI 预览不显示(无错误)

jquery - Bootstrap 选项卡 : strange behaviour in ios chrome

ios - 在相机 View 上显示自定义按钮

ios - 由于解包导致网络调用失败

javascript - 无法从 Cloudkit Cloud (JS) 检索所有记录

ios - 如何从 iCloud 获取所有待处理的通知并通知它我的应用程序收到了通知?