作者:mobiledu2502889113 | 来源:互联网 | 2023-02-03 17:25
Apple非常清楚,在每个视频中他们都说"处理错误的CloudKit应用程序与不处理错误的应用程序之间的差异是工作应用程序与不支持工作应用程序之间的区别".但是,我无法在任何地方找到每个错误意味着什么的正确列表,哪些操作会抛出什么或任何示例代码的CloudKit错误处理为各种CKOperations做得很好.更糟糕的是,很多例子根本没有处理错误,我也找不到Apple的任何文档.
有没有人有他们可以分享的完整和完整的例子?哪些操作列表可以抛出什么?
这篇文章显示了错误列表和每个错误的简短描述.我创建了这个新帖子,因为我特意在寻找Apple建议的完整和完整的错误处理示例.另一篇文章有一个不完整的例子,并提出具体问题.我已经在评论中突出显示了这篇文章,因为它包含了每种错误类型的简短描述.
1> user3069232..:
抢,
这是一个例子......
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
}