我正在尝试找到一种比 Google 搜索更简单/更可靠的方法来从错误代码中找出 NSError 的本地化描述。
例如,我知道 NSURLErrorDomain 代码 -1003 对应于“无法找到具有指定主机名的服务器”。但如果我尝试在代码中验证它,它不匹配。
let error = NSError(domain: "NSURLErrorDomain", code: -1003)
print(error.localizedDescription)
// "The operation couldn’t be completed. (NSURLErrorDomain error -1003.)"
在 documentation 中查找 -1003 也不匹配:“无法解析 URL 的主机名。”
因此,我正在寻找一种方法来从带有函数的错误代码中找出描述,或者从具有我期望的描述的文档中找出描述。我希望有一个类似于
HTTPURLResponse.localizedString(forStatusCode:)
的功能
当您像这样创建自己的
NSError
对象时,不会为您生成 localizedDescription
。但是,当 URLSession
生成错误对象时,会填充本地化描述:
let url = URL(string: "https://bad.domain")!
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error as? URLError {
print(error.localizedDescription) // “A server with the specified hostname could not be found.”
}
}.resume()
因此,如果您遇到错误并想查看本地化描述,请这样做。如果您手动创建自己的
NSError
对象,它根本不起作用。
但一般来说,我们不会担心本地化描述,而是测试
code
的各种
URLError
值,寻找 code
的 .cannotFindHost
:
let url = URL(string: "https://bad.domain")!
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error as? URLError {
switch error.code {
case .cannotFindHost: print("cannotFindHost")
case .cancelled: print("cancelled")
case .badURL: print("badURL")
// ...
default: break
}
}
}.resume()
或者,您也可以使用
NSURLError
搜索旧的 NSError
代码值,寻找 NSURLErrorCannotFindHost
:
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error as NSError? {
switch error.code {
case NSURLErrorCannotFindHost: print("cannotFindHost")
case NSURLErrorCancelled: print("cancelled")
case NSURLErrorBadURL: print("badURL")
// ...
default: break
}
}
}.resume()
您也可以通过按shift-命令-O(字母“Oh”)来“快速打开”,搜索
NSURLError
,取消勾选快速打开右上角的“Swift”按钮对话:
当您打开
NSURLError.h
文件时,您可以看到其中列出的所有代码。
但是,不,仅通过使用指定的域和代码创建
NSError
,localizedDescription
不会神奇地为您填充。不过,URLSession
创建了带有描述的正确错误对象。
不,大多数事情都没有自动查找(有使用 SecCopyErrorMessageString 的安全错误,但一般情况下不是)。您必须检查标题。这是在 NSURLError.h 中:
NSURLErrorCannotFindHost = -1003,
通常,您要查找的字符串将位于 NSError 的 userInfo 中,并由生成错误的事物放置在那里。它不会从代码中查找到。当 userInfo 中没有消息时,
localizedDescription
默认是写“操作无法完成...”
我不相信有任何内置方法可以生成“像系统那样”的错误。 (这非常依赖于子系统,因为 URLErrors 有很多需要填写的键,这些键不适用于其他类型的错误。)
各位,我想添加此链接供其他人在尝试识别特定错误代码号时参考。 GitHub 上的 Swift.org 开源项目提供的错误代码
您可以对
URLError.Code
进行以下扩展,以便从 URLError.Code 获取可读的原因。
extension URLError.Code: CustomDebugStringConvertible {
public var debugDescription: String {
switch self {
case .unknown:
"URLError.Code.unknown: \(rawValue)"
case .cancelled:
"URLError.Code.cancelled: \(rawValue)"
case .badURL:
"URLError.Code.badURL: \(rawValue)"
case .timedOut:
"URLError.Code.timedOut: \(rawValue)"
case .unsupportedURL:
"URLError.Code.unsupportedURL: \(rawValue)"
case .cannotFindHost:
"URLError.Code.cannotFindHost: \(rawValue)"
case .cannotConnectToHost:
"URLError.Code.cannotConnectToHost: \(rawValue)"
case .networkConnectionLost:
"URLError.Code.networkConnectionLost: \(rawValue)"
case .dnsLookupFailed:
"URLError.Code.dnsLookupFailed: \(rawValue)"
case .httpTooManyRedirects:
"URLError.Code.httpTooManyRedirects: \(rawValue)"
case .resourceUnavailable:
"URLError.Code.resourceUnavailable: \(rawValue)"
case .notConnectedToInternet:
"URLError.Code.notConnectedToInternet: \(rawValue)"
case .redirectToNonExistentLocation:
"URLError.Code.redirectToNonExistentLocation: \(rawValue)"
case .badServerResponse:
"URLError.Code.badServerResponse: \(rawValue)"
case .userCancelledAuthentication:
"URLError.Code.userCancelledAuthentication: \(rawValue)"
case .userAuthenticationRequired:
"URLError.Code.userAuthenticationRequired: \(rawValue)"
case .zeroByteResource:
"URLError.Code.zeroByteResource: \(rawValue)"
case .cannotDecodeRawData:
"URLError.Code.cannotDecodeRawData: \(rawValue)"
case .cannotDecodeContentData:
"URLError.Code.cannotDecodeContentData: \(rawValue)"
case .cannotParseResponse:
"URLError.Code.cannotParseResponse: \(rawValue)"
case .appTransportSecurityRequiresSecureConnection:
"URLError.Code.appTransportSecurityRequiresSecureConnection: \(rawValue)"
case .fileDoesNotExist:
"URLError.Code.fileDoesNotExist: \(rawValue)"
case .fileIsDirectory:
"URLError.Code.fileIsDirectory: \(rawValue)"
case .noPermissionsToReadFile:
"URLError.Code.noPermissionsToReadFile: \(rawValue)"
case .dataLengthExceedsMaximum:
"URLError.Code.dataLengthExceedsMaximum: \(rawValue)"
case .secureConnectionFailed:
"URLError.Code.secureConnectionFailed: \(rawValue)"
case .serverCertificateHasBadDate:
"URLError.Code.serverCertificateHasBadDate: \(rawValue)"
case .serverCertificateUntrusted:
"URLError.Code.serverCertificateUntrusted: \(rawValue)"
case .serverCertificateHasUnknownRoot:
"URLError.Code.serverCertificateHasUnknownRoot: \(rawValue)"
case .serverCertificateNotYetValid:
"URLError.Code.serverCertificateNotYetValid: \(rawValue)"
case .clientCertificateRejected:
"URLError.Code.clientCertificateRejected: \(rawValue)"
case .clientCertificateRequired:
"URLError.Code.clientCertificateRequired: \(rawValue)"
case .cannotLoadFromNetwork:
"URLError.Code.cannotLoadFromNetwork: \(rawValue)"
case .cannotCreateFile:
"URLError.Code.cannotCreateFile: \(rawValue)"
case .cannotOpenFile:
"URLError.Code.cannotOpenFile: \(rawValue)"
case .cannotCloseFile:
"URLError.Code.cannotCloseFile: \(rawValue)"
case .cannotWriteToFile:
"URLError.Code.cannotWriteToFile: \(rawValue)"
case .cannotRemoveFile:
"URLError.Code.cannotRemoveFile: \(rawValue)"
case .cannotMoveFile:
"URLError.Code.cannotMoveFile: \(rawValue)"
case .downloadDecodingFailedMidStream:
"URLError.Code.downloadDecodingFailedMidStream: \(rawValue)"
case .downloadDecodingFailedToComplete:
"URLError.Code.downloadDecodingFailedToComplete: \(rawValue)"
case .internationalRoamingOff:
"URLError.Code.internationalRoamingOff: \(rawValue)"
case .callIsActive:
"URLError.Code.callIsActive: \(rawValue)"
case .dataNotAllowed:
"URLError.Code.dataNotAllowed: \(rawValue)"
case .requestBodyStreamExhausted:
"URLError.Code.requestBodyStreamExhausted: \(rawValue)"
case .backgroundSessionRequiresSharedContainer:
"URLError.Code.backgroundSessionRequiresSharedContainer: \(rawValue)"
case .backgroundSessionInUseByAnotherProcess:
"URLError.Code.backgroundSessionInUseByAnotherProcess: \(rawValue)"
case .backgroundSessionWasDisconnected:
"URLError.Code.backgroundSessionWasDisconnected: \(rawValue)"
default:
"URLError.Code.unknownError: \(rawValue)"
}
}
}
希望这有帮助。