ios - 处理 CloudKit 错误

标签 ios swift error-handling cloudkit

我正在寻找有关在 Swift 中处理 CloudKit 错误的一般建议,但在网上找不到好的示例时遇到了麻烦。以下是我想知道的事情:

1) 每次出现错误的可能性时,我是否应该考虑每种错误类型,还是真的没有必要?

2) 我了解到处理 CloudKit 错误的一种常见方法是在错误消息提供的时间间隔后重试执行操作。这种重试基本上应该是我针对所有错误的标准程序吗?

3) 不同的 CloudKit 操作(保存、获取等)是否会产生不同类型的错误,或者是否存在一组标准的 CloudKit 错误?

提前致谢!我只是在寻找有关如何使用 CloudKit 处理错误的一般信息,因为我不确定从哪里开始。

最佳答案

是的,您想检查每个 cloudkit 调用是否有错误。 Apple 在与 cloudkit 相关的 WWDC 视频中强调了这一点。

当您检测到错误时,您所采取的措施差异很大。重试有时是一种选择,但有时并不合适。如果您正在使用批处理操作,重试可能需要一些额外的工作来提取失败的记录。所以,是的,您有时可能想重试,但不会,您可能不会自动重试每个失败的操作。

CKError.h 中定义了一组错误。但是,您并不总是只得到 CKError。有时,尤其是对于 CKErrorPartialFailure,您会得到一个顶级错误,其中包含您还必须解包的嵌套错误。从 IOS 10 开始,CKError.h 中的错误列表如下所示:

typedef NS_ENUM(NSInteger, CKErrorCode) {
    CKErrorInternalError                  = 1,  /* CloudKit.framework encountered an error.  This is a non-recoverable error. */
    CKErrorPartialFailure                 = 2,  /* Some items failed, but the operation succeeded overall. Check CKPartialErrorsByItemIDKey in the userInfo dictionary for more details. */
    CKErrorNetworkUnavailable             = 3,  /* Network not available */
    CKErrorNetworkFailure                 = 4,  /* Network error (available but CFNetwork gave us an error) */
    CKErrorBadContainer                   = 5,  /* Un-provisioned or unauthorized container. Try provisioning the container before retrying the operation. */
    CKErrorServiceUnavailable             = 6,  /* Service unavailable */
    CKErrorRequestRateLimited             = 7,  /* Client is being rate limited */
    CKErrorMissingEntitlement             = 8,  /* Missing entitlement */
    CKErrorNotAuthenticated               = 9,  /* Not authenticated (writing without being logged in, no user record) */
    CKErrorPermissionFailure              = 10, /* Access failure (save, fetch, or shareAccept) */
    CKErrorUnknownItem                    = 11, /* Record does not exist */
    CKErrorInvalidArguments               = 12, /* Bad client request (bad record graph, malformed predicate) */
    CKErrorResultsTruncated NS_DEPRECATED(10_10, 10_12, 8_0, 10_0, "Will not be returned") = 13,
    CKErrorServerRecordChanged            = 14, /* The record was rejected because the version on the server was different */
    CKErrorServerRejectedRequest          = 15, /* The server rejected this request.  This is a non-recoverable error */
    CKErrorAssetFileNotFound              = 16, /* Asset file was not found */
    CKErrorAssetFileModified              = 17, /* Asset file content was modified while being saved */
    CKErrorIncompatibleVersion            = 18, /* App version is less than the minimum allowed version */
    CKErrorConstraintViolation            = 19, /* The server rejected the request because there was a conflict with a unique field. */
    CKErrorOperationCancelled             = 20, /* A CKOperation was explicitly cancelled */
    CKErrorChangeTokenExpired             = 21, /* The previousServerChangeToken value is too old and the client must re-sync from scratch */
    CKErrorBatchRequestFailed             = 22, /* One of the items in this batch operation failed in a zone with atomic updates, so the entire batch was rejected. */
    CKErrorZoneBusy                       = 23, /* The server is too busy to handle this zone operation. Try the operation again in a few seconds. */
    CKErrorBadDatabase                    = 24, /* Operation could not be completed on the given database. Likely caused by attempting to modify zones in the public database. */
    CKErrorQuotaExceeded                  = 25, /* Saving a record would exceed quota */
    CKErrorZoneNotFound                   = 26, /* The specified zone does not exist on the server */
    CKErrorLimitExceeded                  = 27, /* The request to the server was too large. Retry this request as a smaller batch. */
    CKErrorUserDeletedZone                = 28, /* The user deleted this zone through the settings UI. Your client should either remove its local data or prompt the user before attempting to re-upload any data to this zone. */
    CKErrorTooManyParticipants            NS_AVAILABLE(10_12, 10_0) = 29, /* A share cannot be saved because there are too many participants attached to the share */
    CKErrorAlreadyShared                  NS_AVAILABLE(10_12, 10_0) = 30, /* A record/share cannot be saved, doing so would cause a hierarchy of records to exist in multiple shares */
    CKErrorReferenceViolation             NS_AVAILABLE(10_12, 10_0) = 31, /* The target of a record's parent or share reference was not found */
    CKErrorManagedAccountRestricted       NS_AVAILABLE(10_12, 10_0) = 32, /* Request was rejected due to a managed account restriction */
    CKErrorParticipantMayNeedVerification NS_AVAILABLE(10_12, 10_0) = 33, /* Share Metadata cannot be determined, because the user is not a member of the share.  There are invited participants on the share with email addresses or phone numbers not associated with any iCloud account. The user may be able to join the share if they can associate one of those email addresses or phone numbers with their iCloud account via the system Share Accept UI. Call UIApplication's openURL on this share URL to have the user attempt to verify their information. */
} NS_ENUM_AVAILABLE(10_10, 8_0);

在开发和测试应用程序时,一种方法是检查每个 cloudkit 操作是否有错误,如果检测到错误,则触发 NSAssert 以停止应用程序。然后,检查错误、潜在错误和上下文以确定它失败的原因以及您需要采取的措施。很可能,随着时间的推移,您会看到常见的模式出现,然后您可以考虑构建一个通用的错误处理程序。

关于ios - 处理 CloudKit 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43553969/

相关文章:

ios - 数据未显示在标签中

ios - 在此设备上启用开发时遇到错误

php - 仅限 php fatal error 的 error_reporting 编号是多少?

python - 函数在单独的实例中以不同的方式运行-python

ios - 当按下 map View 注释时,如何使用 segue 在详细 View 中显示 plist 中的数据

ios - 每次更改子项时都会调用添加的 Firebase 子项

swift - firebaseui ios : don't show email sign in option

ios - UI 旋转手势识别器捕捉直角

ios - 经常访问 NSUserDefaults/UserDefaults 可以吗?

Kotlin:尝试,捕捉,并且只有在最后出现错误时