如何在Swift中使用Error型別提供本地化的描述?


Swift 提供了一個協議來實現本地化描述。您可以使用 `LocalizedError` 協議來提供錯誤型別的本地化描述。結構體、列舉或類都可以遵循此協議。採用此協議後,您必須實現 `errorDescription` 屬性來提供本地化描述。

這是一個遵循 `LocalizedError` 協議的自定義錯誤列舉示例:

建立一個自定義錯誤並符合 `Error` 型別

在這個例子中,我們將建立一個名為 `CustomError` 的列舉來符合 `LocalizedError` 協議。在列舉中,我們將新增 case 來定義不同型別的錯誤。每個錯誤都將代表一個不同的錯誤。以下是如何建立一個帶有 `Error` 型別的列舉的示例:

示例

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` 並帶有 `Error` 型別的列舉。我們將使用相同的列舉來符合不同的協議以本地化描述。

符合 `CustomStringConvertible` 協議

首先,我們將看到一個使用 `CustomStringConvertible` 協議的示例。使用它,您可以為每種型別的錯誤提供自定義訊息。要提供自定義訊息,您可以覆蓋 `description` 屬性。

示例

這是一個透過符合 `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` 為自定義錯誤新增 `localizedDescription`

在此步驟中,您將看到如何符合 `LocalizedError` 協議以針對每種錯誤型別提供本地化描述。一旦您符合 `LocalizedError` 協議,您可以覆蓋 `errorDescription` 屬性來提供本地化。

示例

這是一個使用 `LocalizedError` 協議擴充套件 `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` 協議透過覆蓋 `description` 屬性來提供自定義訊息。您可以為每種錯誤型別提供有意義的訊息。`LocalizedError` 協議也可以用來提供錯誤型別的本地化描述。當發生錯誤時,使用此功能顯示使用者友好的訊息是一個好習慣。

更新於:2023年2月28日

3K+ 次瀏覽

啟動您的職業生涯

完成課程獲得認證

開始學習
廣告
© . All rights reserved.