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
というメッセージが表示されるようになります。