Swiftでカスタムエラーを実装ときたら、何も考えずErrorプロトコルに準拠させたEnum型として実装してましたが、ある時想定したエラーメッセージが表示できてないことに気づきました。
以下はRxSwiftで実装したコードです。
ViewModel.errorsはSignal<Error>型のプロパティで、様々なエラーイベントが流れてきます。
そしてUIAlertControllerでエラーメッセージを表示させています。
viewModel.errors
.emit(onNext: { [unowned self] in
let alert = UIAlertController.makeErrorAlertController(error: $0)
self.present(alert, animated: true)
})
.disposed(by: disposeBag)
流すエラーは例えばこんな感じで、Errorプロトコルに準拠させたEnumです。
enum AppError: Error {
case unknown
var localizedDescription: String {
switch self {
case .unknown: return "unknown error happened"
}
}
}
このエラーがViewModelから流れてきて画面にエラーメッセージを表示させる(localizedDescriptionプロパティを参照する)と、、
The operation couldn’t be completed. (Example.AppError error 0.)
unknown error happenedになってない。
まあよく考えれば当たり前で、このメッセージはAppError型のlocalizedDescriptionで実装されているのであって、ViewModelから流れてくるのはError型なのでlocalizedDescriptionのデフォルト実装によってメッセージが生成されてこの形になっています。
表示ロジックは変えずにlocalizedDescriptionで自分が定義したメッセージを表示できるようにするには、LocalizedErrorプロトコルに準拠させると良いです。
enum AppError: Error {
case unknown
}
extension AppError: LocalizedError {
var errorDescription: String? {
switch self {
case .unknown: return "unknown error happened"
}
}
}
errorDescriptionプロパティを実装すると、Error.localizedDescriptionはこのプロパティを参照してくれます。
これで画面にunknown error happenedというメッセージが表示されるようになります。