CloudKit-完整而完整的错误处理示例 [英] CloudKit - full and complete error handling example

查看:132
本文介绍了CloudKit-完整而完整的错误处理示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Apple非常清楚,在每个视频中他们都说:处理错误的CloudKit应用程序与不处理错误的CloudKit应用程序之间的区别是,正常工作的应用程序与未处理的应用程序之间的区别。但是,我找不到任何错误含义的正确列表,哪些操作会抛出CloudKit错误处理的示例代码或任何示例代码,对于各种CKOperation来说都做得很好。更糟糕的是,许多示例根本无法处理错误,我也无法从Apple那里找到任何文档。

Apple are very clear, in every video they state that "The difference between a CloudKit app which handles errors and one that doesn't is the difference between a working app and one that doesn't". However, I can't find anywhere a proper list of what each error means, which Operations throw what or any example code of CloudKit error handling done well for various CKOperations. Even worse, many examples don't handle errors at all and I can't find any documentation from Apple either.

任何人都拥有可以共享的完整示例吗? ?
哪些操作可以抛出什么清单?

Does anyone have a full and complete example they can share? Any lists of which Operations can throw what?

这篇文章显示了错误列表以及每个错误的简短说明。我之所以创建此新帖子,是因为我专门寻找Apple建议的完整和完整的错误处理示例。另一则帖子的示例不完整,正在询问具体问题。我已经在注释中突出显示了该帖子,因为它包含每种有用的错误类型的简短描述。

This post shows a list of errors and a short description of each error. I created this new post because I'm specifically looking for full and complete examples of error handling as Apple recommends. The other post has an incomplete example and is asking specific questions. I already highlighted this post in the comments because it contains a short description of each error type which is useful.

推荐答案

Rob,

下面是一个示例...

Here an example...

func files_saveNotes(rex: Int) {
     var localChanges:[CKRecord] = []

        let newRecordID = CKRecordID(recordName: sharedDataAccess.returnRexID(index2seek: rex))
        let newRecord = CKRecord(recordType: "Note", recordID: newRecordID)

        let theLinkID = CKReference(recordID: sharedDataAccess.iCloudID, action: .deleteSelf)
        let thePath = sharedDataAccess.fnGet(index2seek: rex)
        newRecord["theLink"] = theLinkID
        newRecord["theNo"] = rex as CKRecordValue?
        newRecord["thePath"] = thePath as CKRecordValue?



        let miam = sharedDataAccess.fnGetText(index2seek: rex)
        let range = NSRange(location: 0, length: miam.length)
        let dataMiam = try? miam.data(from: range, documentAttributes: [NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType])

        newRecord["theRTF"] = dataMiam as? CKRecordValue


    localChanges.append(newRecord)
    let records2Erase:[CKRecordID] = []

    let saveRecordsOperation = CKModifyRecordsOperation(recordsToSave: localChanges, recordIDsToDelete: records2Erase)
    saveRecordsOperation.savePolicy = .allKeys
    saveRecordsOperation.perRecordCompletionBlock =  { record, error in
        if error != nil {
            //print(error!.localizedDescription)
        }
        // deal with conflicts
        // set completionHandler of wrapper operation if it's the case
    }
    saveRecordsOperation.modifyRecordsCompletionBlock = { savedRecords, deletedRecordIDs, error in
        self.theApp.isNetworkActivityIndicatorVisible = false

        guard error == nil else {
            if let ckerror = error as? CKError {
                if ckerror.code == CKError.requestRateLimited {
                    let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
                    DispatchQueue.main.async {
                        Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.files_saveNotes), userInfo: nil, repeats: false)
                    }
                } else if ckerror.code == CKError.zoneBusy {
                    let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
                    DispatchQueue.main.async {
                        Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.files_saveNotes), userInfo: nil, repeats: false)
                    }
                } else if ckerror.code == CKError.limitExceeded {
                    let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
                    DispatchQueue.main.async {
                        Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.files_saveNotes), userInfo: nil, repeats: false)
                    }
                } else if ckerror.code == CKError.notAuthenticated {
                    NotificationCenter.default.post(name: Notification.Name("noCloud"), object: nil, userInfo: nil)
                } else if ckerror.code == CKError.networkFailure {
                    NotificationCenter.default.post(name: Notification.Name("networkFailure"), object: nil, userInfo: nil)
                } else if ckerror.code == CKError.networkUnavailable {
                    NotificationCenter.default.post(name: Notification.Name("noWiFi"), object: nil, userInfo: nil)
                } else if ckerror.code == CKError.quotaExceeded {
                    NotificationCenter.default.post(name: Notification.Name("quotaExceeded"), object: nil, userInfo: nil)
                } else if ckerror.code == CKError.partialFailure {
                    NotificationCenter.default.post(name: Notification.Name("partialFailure"), object: nil, userInfo: nil)
                } else if (ckerror.code == CKError.internalError || ckerror.code == CKError.serviceUnavailable) {
                    NotificationCenter.default.post(name: Notification.Name("serviceUnavailable"), object: nil, userInfo: nil)
                }
            } // end of guard statement
            return
        }
        if error != nil {
            //print(error!.localizedDescription)
        } else {
            //
        }
    }

    saveRecordsOperation.qualityOfService = .background
    privateDB.add(saveRecordsOperation)
    theApp.isNetworkActivityIndicatorVisible = true
}

这篇关于CloudKit-完整而完整的错误处理示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆