Swift 如何用一个错误类型提供本地化描述

Swift 如何用一个错误类型提供本地化描述

Swift提供了一个协议来实现本地化描述。你可以使用 LocalizedError 协议来提供一个错误类型的本地化描述。这个协议可以通过结构、枚举或类来符合。采用这个协议后,你必须实现errorDescription属性以提供本地化描述。

下面是一个符合本地化错误协议的自定义错误枚举的例子:

创建一个自定义的错误并符合错误类型

在这个例子中,我们将创建一个名为CustomError的枚举,以符合LocalizedError协议。在这个枚举中,我们将添加案例来定义不同类型的错误。每个错误将代表一个不同的错误。下面是创建一个具有错误类型的枚举的例子:

例子

import Foundation
// An enum with different error types.
enum CustomError: Error {
   case invalidUrl
   case httpError
   case timeoutError
   case noConnectionError
   case encodingError
   case decodingError
   case invalidResponseError
   case unexpected(code: Int)
}

在上面的代码中,我们创建了一个名为CustomError的枚举,带有错误类型。同样的枚举,我们将用来符合不同的协议来进行本地化描述。

符合CustomStringConvertible协议

首先,我们将看到一个使用CustomStringConvertible协议的例子。使用这个,你可以为每种类型的错误提供一个自定义的消息。为了提供一个自定义的消息,你可以覆盖描述属性。

例子

下面是一个通过符合CustomStringConvertible协议来扩展CustomError枚举的例子:

// Assign an appropriate description to each type of error.
extension CustomError: CustomStringConvertible {

   var description: String {
      switch self {
         case .invalidUrl:
            return "There is a problem with a URL, such as an invalid URL or a timeout."

         case .httpError:
            return "There is an issue with an HTTP request or response."

         case .timeoutError:
            return "The request takes longer than the specified timeout period to complete."

         case .noConnectionError:
            return "There is no internet connection or the device is offline."

         case .encodingError:
            return "The data received from the server is unable to be encoded as the expected type."

         case .decodingError:
            return "The data received from the server is unable to be decoded as the expected type."

         case .invalidResponseError:
            return "The server responds with an unexpected format or status code."

         case .unexpected(let code):
            return "There is an unexpected error with the code \(code)"
      }
   }
}

使用LocalizedError为自定义错误添加本地化描述

在这一步,你将看到如何符合LocalizedError协议,为每个错误类型提供本地化的描述。一旦你符合LocalizedError协议,你可以覆盖errorDescription属性以提供本地化。

例子

下面是一个用本地化错误协议扩展CustomError枚举的例子。

// Assign a localized description to each type of error.
extension CustomError: LocalizedError {

   var errorDescription: String? {
      switch self {
         case .invalidUrl:
            return NSLocalizedString("There is a problem with a URL, such as an invalid URL or a timeout.", comment: "Invalid URL")

         case .httpError:
            return NSLocalizedString("There is an issue with an HTTP request or response.", comment: "HTTP Error")

         case .timeoutError:
            return NSLocalizedString("The request takes longer than the specified timeout period to complete.", comment: "Timeout Error")

         case .noConnectionError:
            return NSLocalizedString("There is no internet connection or the device is offline.", comment: "Internet Connection Error")

         case .encodingError:
            return NSLocalizedString("The data received from the server is unable to be encoded as the expected type.", comment: "Encoding Error")

         case .decodingError:
            return NSLocalizedString("The data received from the server is unable to be decoded as the expected type.", comment: "Decoding Error")

         case .invalidResponseError:
            return NSLocalizedString("The server responds with an unexpected format or status code.", comment: "Invalid Response Error")

         case .unexpected(let code):
            return NSLocalizedString("There is an unexpected error with the code \(code)", comment: "Unexpected Error")
      }
   }
}

扩展自定义错误

在Swift中,枚举具有更多的功能,可以让你扩展它的功能。你可以向枚举添加计算属性和函数。

我们将添加一个计算属性来确定错误是否是致命的类型。换句话说,我们将检查该错误是否可以被处理。比如说–

// Checking for unexpected errors that cannot be handled.
extension CustomError {
   var isFatal: Bool {
      if case CustomError.unexpected = self { return true }
      else { return false }
   }
}

实际用法

我们已经准备好了带有本地化描述的自定义错误。现在,让我们看看如何在你的项目中使用它们。

例子

func checkServerResponse(_ response: [String: Any]?) -> CustomError? {

   // check for valid response
   guard let responseDictionary = response else {
      return CustomError.invalidResponseError
   }

   // check for valid status code
   guard let statusCode = responseDictionary["statusCode"] as? Int,
      statusCode >= 200 && statusCode <= 300  else {
      return CustomError.unexpected(code: -1002)
   }

   // check for valid data object
   guard let dataDictionary = responseDictionary["data"] as? [String: Any] else {
      return CustomError.encodingError
   }

   print("Received Data: \(dataDictionary)")
   return nil
}
let response: [String: Any] = ["statusCode": 201, "data": "user name"]
if let error = checkServerResponse(response) {
   print("Error description: \(error.description)\nLocalized Description: \(error.localizedDescription)\nFatal Status: \(error.isFatal)")
}

输出

Error description: The data received from the server is unable to be encoded as the expected type.
Localized Description: The data received from the server is unable to be encoded as the expected type.
Fatal Status: false

在上面的例子中,我们创建了一个函数来检查从服务器收到的响应。如果发现任何错误,这个函数会返回一个自定义的可选类型的错误类型。

在函数的实现中,我们检查不同的有效情况。在每次检查时,如果有错误,就返回一个自定义的错误。

结论

在实际应用中,大部分时间你都在处理网络请求。很明显,你必须管理不同类型的错误。在Swift中,有一些协议是你可以遵守的,并扩展了用自定义消息或本地化描述来理解错误的能力。

CustomStringConvertible协议可以用来通过覆盖描述属性来提供自定义消息。你可以为每个错误类型提供有意义的消息。LocalizedError协议也可以用来提供一个错误类型的本地化描述。当一个错误发生时,使用这个功能来显示一个用户友好的信息是很好的做法。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

Swift 示例