Как обеспечить локализованное описание с типом ошибки в Swift?

Я определяю настраиваемый тип ошибки с синтаксисом Swift 3, и я хочу предоставить удобное описание ошибки, которая возвращается свойством localizedDescription объекта Error . Как мне это сделать?

 public enum MyError: Error { case customError var localizedDescription: String { switch self { case .customError: return NSLocalizedString("A user-friendly description of the error.", comment: "My error") } } } let error: Error = MyError.customError error.localizedDescription // "The operation couldn't be completed. (MyError error 0.)" 

Есть ли способ для localizedDescription вернуть мое описание ошибки («Удобное описание ошибки»)? Обратите внимание, что здесь объект ошибки имеет тип Error а не MyError . Я могу, конечно, бросить объект в MyError

 (error as? MyError)?.localizedDescription 

но есть ли способ заставить его работать, не отбрасывая мой тип ошибки?

Как описано в примечаниях к выпуску Xcode 8 beta 6,

Быстрые типы ошибок могут предоставлять локализованные описания ошибок, приняв новый протокол LocalizedError.

В твоем случае:

 public enum MyError: Error { case customError } extension MyError: LocalizedError { public var errorDescription: String? { switch self { case .customError: return NSLocalizedString("A user-friendly description of the error.", comment: "My error") } } } let error: Error = MyError.customError print(error.localizedDescription) // A user-friendly description of the error. 

Вы можете предоставить еще больше информации, если ошибка преобразована в NSError (что всегда возможно):

 extension MyError : LocalizedError { public var errorDescription: String? { switch self { case .customError: return NSLocalizedString("I failed.", comment: "") } } public var failureReason: String? { switch self { case .customError: return NSLocalizedString("I don't know why.", comment: "") } } public var recoverySuggestion: String? { switch self { case .customError: return NSLocalizedString("Switch it off and on again.", comment: "") } } } let error = MyError.customError as NSError print(error.localizedDescription) // I failed. print(error.localizedFailureReason) // Optional("I don\'t know why.") print(error.localizedRecoverySuggestion) // Optional("Switch it off and on again.") 

Приняв протокол CustomNSError , ошибка может предоставить словарь userInfo (а также domain и code ). Пример:

 extension MyError: CustomNSError { public static var errorDomain: String { return "myDomain" } public var errorCode: Int { switch self { case .customError: return 999 } } public var errorUserInfo: [String : Any] { switch self { case .customError: return [ "line": 13] } } } let error = MyError.customError as NSError if let line = error.userInfo["line"] as? Int { print("Error in line", line) // Error in line 13 } print(error.code) // 999 print(error.domain) // myDomain 

Я бы также добавил, если ваша ошибка имеет такие параметры, как эта

 enum NetworkError: LocalizedError { case responseStatusError(status: Int, message: String) } 

вы можете вызвать эти параметры в своем локализованном описании следующим образом:

 extension NetworkError { var errorDescription: String { switch self { case .responseStatusError(status: let status, message: let message): return "Error with status \(status) and message \(message) was thrown" } } 

Вы даже можете сделать это короче:

 extension NetworkError { var errorDescription: String { switch self { case let .responseStatusError(status, message): return "Error with status \(status) and message \(message) was thrown" } } 

Теперь есть два протокола принятия ошибок, которые может принять ваш тип ошибки, чтобы предоставить дополнительную информацию Objective-C – LocalizedError и CustomNSError. Вот пример ошибки, которая принимает их обоих:

 enum MyBetterError : CustomNSError, LocalizedError { case oops // domain static var errorDomain : String { return "MyDomain" } // code var errorCode : Int { return -666 } // userInfo var errorUserInfo: [String : Any] { return ["Hey":"Ho"] }; // localizedDescription var errorDescription: String? { return "This sucks" } // localizedFailureReason var failureReason: String? { return "Because it sucks" } // localizedRecoverySuggestion var recoverySuggestion: String? { return "Give up" } } 

Вот более элегантное решение:

  enum ApiError: String, LocalizedError { case invalidCredentials = "Invalid credentials" case noConnection = "No connection" var localizedDescription: String { return NSLocalizedString(self.rawValue, comment: "") } } 

Использование структуры может быть альтернативой. Немного элегантность со статической локализацией:

 import Foundation struct MyError: LocalizedError, Equatable { private var description: String! init(description: String) { self.description = description } var errorDescription: String? { return description } public static func ==(lhs: MyError, rhs: MyError) -> Bool { return lhs.description == rhs.description } } extension MyError { static let noConnection = MyError(description: NSLocalizedString("No internet connection",comment: "")) static let requestFailed = MyError(description: NSLocalizedString("Request failed",comment: "")) } func throwNoConnectionError() throws { throw MyError.noConnection } do { try throwNoConnectionError() } catch let myError as MyError { switch myError { case .noConnection: print("noConnection: \(myError.localizedDescription)") case .requestFailed: print("requestFailed: \(myError.localizedDescription)") default: print("default: \(myError.localizedDescription)") } } 
  • Функция преобразования для проверки ошибок считается хорошей?
  • Как получить полезные сообщения об ошибках в PHP?
  • rails 4: страницы пользовательских ошибок для 404, 500 и откуда отправляется сообщение об ошибке по умолчанию 500?
  • Как реализована среда выполнения обработки исключений C ++?
  • Как реализовать правильную обработку ошибок HTTP в .NET MVC 2?
  • Подробное сообщение об ошибке 500, ASP + IIS 7.5
  • обрабатывать ajax-ошибку, когда пользователь нажимает кнопку обновления
  • Google Analytics Google Analytics Ошибка 403: «У пользователя нет учетной записи Google Analytics»
  • Развертывание веб-сайта: 500 - Внутренняя ошибка сервера
  • Давайте будем гением компьютера.