Изменить локализованное описание ошибки

У меня есть класс ошибок:

public enum ModelError: Error {
  case invalidArray(model: String)

  var localizedDescription: String {
    switch self {
    case .invalidArray(model: let model):
      return "\(model) has an invalid array"
    default:
      return "modelError"
    }
  }
}

и когда он передается как Error в функции обратного вызова, я хочу получить доступ к его пользовательскому локализованному описанию. Например:

func report(_ error: Error) {
  print("Error report: \(error.localizedDescription)")
}

Но вызов report(ModelError.invalidArray(model: "test")) печатает:

"The operation couldn’t be completed. (ModelError error 0.)"

Такие вещи кажутся возможными с NSError, поскольку я могу переопределить там свойство localizedDescription. Но я не хочу использовать NSError, так как это не очень быстро, и многие библиотеки работают с Error.


person Guig    schedule 10.11.2016    source источник
comment
Разве ModelError(model: "test") не должно быть ModelError.invalidArray(model: "text") ?   -  person rmaddy    schedule 11.11.2016
comment
да, плохой копипаст. Спасибо!   -  person Guig    schedule 11.11.2016
comment
Я могу заставить ваш код работать, если ModelError соответствует CustomStringConvertible, а localizeDescription переименовывается в description. А затем напечатайте error вместо error.localizedDescription.   -  person rmaddy    schedule 11.11.2016
comment
@rmaddy Разве это не выходит за рамки CustomStringConvertible?   -  person GetSwifty    schedule 11.11.2016
comment
@PEEJWEEJ Я не знаю, не так ли? Я думал, что этот протокол может использоваться всем, кто хочет предоставить метод description. Я все еще изучаю Swift.   -  person rmaddy    schedule 11.11.2016
comment
Это может быть, но цель состоит в том, чтобы он описывал тип, а не давал другую информацию. developer.apple.com/reference/swift/customstringconvertible описание должно выглядеть примерно так: ModelError .invalidArray (тест)   -  person GetSwifty    schedule 11.11.2016
comment
но да, похоже, это дубликат. Хорошо знать   -  person GetSwifty    schedule 11.11.2016
comment
Действительно, спасибо и извините за дубликат   -  person Guig    schedule 11.11.2016


Ответы (1)


Согласно документации, localizedDescription реализуется в расширении протокола, а не в объявлении протокола. , что означает, что нечего придерживаться или переопределять. Существует общетиповой интерфейс для перечислений, которые придерживаются Error.

Мой способ обойти это - использовать протокол-оболочку:

protocol LocalizedDescriptionError: Error {
    var localizedDescription: String { get }
}

public enum ModelError: LocalizedDescriptionError {
    case invalidArray(model: String)

    var localizedDescription: String {
        switch self {
        case .invalidArray(model: let model):
            return "\(model) has an invalid array"
        default:
            return "modelError"
        }
    }
}

let error: LocalizedDescriptionError = ModelError.invalidArray(model: "Model")
let text = error.localizedDescription // Model Has an invalid array
person GetSwifty    schedule 11.11.2016
comment
Вышеупомянутое работает только потому, что вы объявляете константу error как имеющую (специализированный) тип LocalizedDescriptionError. Если вы разрешите ему иметь (базовый) тип Error, он будет отправлен в реализацию по умолчанию в рамках протокола Error, поскольку, как вы упомянули, localizedDescription не объявлен в самом протоколе Error и, следовательно, не может быть переопределен. Вместо этого необходимо использовать новый протокол LocalizedError. - person Gary; 18.01.2017