CKError localizedDescription

7

目的

  • 我希望在应用程序中以警报的形式向用户显示遇到的CKError
  • 因此,我想从错误中提取可向用户显示的字符串。

注意: 这个问题不是关于UI代码的展示,只是想从错误中提取有意义的字符串。

我尝试使用localizedDescription,但似乎没有包含适当的字符串。

代码:

以下是我尝试过的方法:

po error  
<CKError 0x1c464cea0: "Network Unavailable" (3/NSURLErrorDomain:-1009); "The Internet connection appears to be offline.">  

po error.localizedDescription  
"The operation couldn’t be completed. (CKErrorDomain error 3.)"  

po (error as! CKError).errorUserInfo  
▿ 2 elements  
  ▿ 0 : 2 elements  
    - key : "NSUnderlyingError"  
    - value : Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={NSErrorFailingURLStringKey=https:/  
  ▿ 1 : 2 elements  
    - key : "NSDebugDescription"  
    - value : NSURLErrorDomain: -1009  



po (error as? NSError)?.localizedFailureReason  
nil  

po (error as? NSError)?.localizedRecoverySuggestion  
nil  

po (error as? NSError)?.localizedRecoveryOptions  
nil  

po (error as? NSError)?.debugDescription  
▿ Optional<String>  
  - some : "<CKError 0x1c064eaf0: \"Network Unavailable\" (3/NSURLErrorDomain:-1009); \"The Internet connection appears to be offline.\">"  

问题:

调试描述似乎是我想要的最接近的东西。

  1. 我有什么遗漏吗?
  2. 提取错误字符串的正确方法是什么,以便我可以显示给用户?

尝试 (error as! CKError).localizedDescription - Bill
没有进行强制类型转换的情况下产生相同的效果。 - user1046037
我认为最好的做法是将错误代码映射到自己的错误消息。我相信这是苹果推荐的做法,但我记不清在哪里看到过这个建议。 - Duncan Groenewald
@DuncanGroenewald 我同意,如果我们想要一个相关的消息,我认为自定义消息是唯一的选择。这肯定可以改进,提出一个 bug 的建议可能是个好主意。 - user1046037
3个回答

6

看起来errorUserInfo[NSUnderlyingError]中又出现了一个错误。尝试从该错误中获取localizedDescription。

所以,代码应该是这样的:

((error as? CKError)?.errorUserInfo[NSUnderlyingErrorKey] as? NSError)?.localizedDescription

它返回Optional(Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={NSErrorFailingURLStringKey=https://gateway.icloud.com:443/ckdatabase/api/client/query/retrieve, NSErrorFailingURLKey=https://gateway.icloud.com:443/ckdatabase/api/client/query/retrieve, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=50, NSLocalizedDescription=The Internet connection appears to be offline.})。这对用户来说太技术化了,难以理解。 - user1046037
我只是觉得CKError有一个bug,localizedDescription没有适当地填充。 - user1046037
您评论中的本地化描述为“互联网连接似乎已离线。”。这就是您所需要的。 - Richard Venable
它不是一个独立的键“NSLocalizedDescription”,而是长错误消息的一小部分。因此,像那样提取它是不可靠的。 - user1046037
不,那里面有一个单独的错误。我更新了我的答案,并提供了代码以帮助您找出它。 - Richard Venable
太棒了!!!非常好用。让我的一天变得美好...非常感谢!!!你已经在使用这个工具了还是刚刚发现它? - user1046037

4
error.localizedDescription 是您从错误本身获取的全部信息。
通过检查错误代码并向用户提供自己的消息,您的应用程序可以提供更好的错误消息(更用户友好、本地化等)。
(error as? NSError)?.code

很不幸,本地化描述并没有提供有意义的描述。而我自己处理错误消息的问题在于有26个错误代码。如果我要支持5种语言,那么就会有26 x 5 = 130个错误消息。可悲的是它们确实在调试描述中有这个错误但却带有技术信息。我认为这更像是一个漏洞,想知道是否有解决方案。 - user1046037

2

我并不为此感到骄傲,但这是我采取的方式。一定有更好的方法!

public func ckErrorCodeToText(code: CKError.Code) -> String {
    switch code {
    case .alreadyShared: return "alreadyShared"
    case .internalError: return "internalError"
    case .partialFailure: return "partialFailure"
    case .networkUnavailable: return "networkUnavailable"
    case .networkFailure: return "networkFailure"
    case .badContainer: return "badContainer"
    case .serviceUnavailable: return "serviceUnavailable"
    case .requestRateLimited: return "requestRateLimited"
    case .missingEntitlement: return "missingEntitlement"
    case .notAuthenticated: return "notAuthenticated"
    case .permissionFailure: return "permissionFailure"
    case .unknownItem: return "unknownItem"
    case .invalidArguments: return "invalidArguments"
    case .resultsTruncated: return "resultsTruncated"
    case .serverRecordChanged: return "serverRecordChanged"
    case .serverRejectedRequest: return "serverRejectedRequest"
    case .assetFileNotFound: return "assetFileNotFound"
    case .assetFileModified: return "assetFileModified"
    case .incompatibleVersion: return "incompatibleVersion"
    case .constraintViolation: return "constraintViolation"
    case .operationCancelled: return "operationCancelled"
    case .changeTokenExpired: return "changeTokenExpired"
    case .batchRequestFailed: return "batchRequestFailed"
    case .zoneBusy: return "zoneBusy"
    case .badDatabase: return "badDatabase"
    case .quotaExceeded: return "quotaExceeded"
    case .zoneNotFound: return "zoneNotFound"
    case .limitExceeded: return "limitExceeded"
    case .userDeletedZone: return "userDeletedZone"
    case .tooManyParticipants: return "tooManyParticipants"
    case .referenceViolation: return "referenceViolation"
    case .managedAccountRestricted: return "managedAccountRestricted"
    case .participantMayNeedVerification: return "participantMayNeedVerification"
    case .serverResponseLost: return "serverResponseLost"
    case .assetNotAvailable: return "assetNotAvailable"
    @unknown default: return String(code.rawValue)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接