Help us understand the problem. What is going on with this article?

NSErrorが便利すぎる件 Appleありがとう

More than 3 years have passed since last update.

NSErrorを返す系のメソッドを使う機会って良くあると思いますが(通信,保存など)、NSErrorの引数にnil以外(エラー)の場合どうしたらいいか分からないということが多々あるのではないでしょうか?

「だって、NSErrorにどういう内容が返ってくるか分からないし、分かったとしても全てのパターンにおいてエラー処理書かないといけないの?」的な。

だからNSErrorにエラーが返ってきたら、何もしない。
落ちるか落ちないかは神のみぞ知る的な。

やっぱりそれじゃちょっとダメプログラマかなと思い、エラーメッセくらい出してあげるか、ということでNSErrorの仕様読んでたらとんでもなく便利なことに気づいたので共有します。

UIAlertViewに表示する内容を全部『日本語』で返してくれる

※ UIAlertViewはios8からdeprecatedなので注意してね、俺は面倒くさいからUIAlertViewでやってるけどね爆

NSErrorのプロパティを簡単にご紹介

・localizedDescription
  → エラーの概要
・localizedFailureReason
  → エラーが発生した理由
・localizedRecoverySuggestion
  → 復旧方法(NextAction)
・localizedRecoveryOptions
  → AlertViewに表示するボタンの名前
  
これ何が便利かというとこれ全部ローカライズして返してくれるというところです。
普通だと「エラーコードを見て、それに対するメッセージを記述したリストを用意して、そして他言語対応するなら言語毎に用意して…」的なことをやる必要があると思いますが、フレームワーク側でローカライズしてくれるので、NSErrorに入っているプロパティをそのままUIAlertViewに表示してやれば、 ローカライズ完了 ということになります。

オススメの方法

UIAlertViewに表示するメッセージのオススメの方法ですが、

UIAlerViewの[title]には復旧方法がかかれている[localizedRecoverySuggestion]を突っ込む。

UIAlertViewの[message]には
[localizedDescription]はエラーの概要といった感じで、[localizedFailureReason]はそれをも少し詳しくといった感じだったので、
[localizedFailureReason]を突っ込む。

UIAlertViewのボタンに設定する文言は
[localizedRecoveryOptions]と思ってしまいますが、これは配列で返ってくるため、そのまま突っ込んでしまうと、ボタンによる処理分けをする必要があります。
そうなると、[localizedRecoverySuggestion]の内容から判断し処理を書かなければなくなり一気に、やらないといけないことが増えるので嫌です。(いや、できればした方がいいですが…)

なので、ここは割り切ってエラーメッセージを出すだけにします。

かつ、
・localizedFailureReason
・localizedRecoverySuggestion
・localizedRecoveryOptions
この3つのプロパティはオプショナル型なので返ってくるかどうか解かりません。

それを踏まえて、実際のコード書きます。

面倒くさいエラー処理の応急処置

とりあえず、以下のように書いておけば最低限のエラー処理にはなってるかなという感じです。
どこでも使えるようにUIViewControllerのextensionとして定義したので、良ければコピペってください。

ShowErrorAlertExtension.swift
import UIKit

extension UIViewController {
    func showErrorAlert(error:NSError){
        var title:String!
        var message:String?
        var btnTitle:String!
        if error.localizedFailureReason == nil{
            message = error.localizedDescription
        }else{
            message = error.localizedFailureReason
        }
        if let suggestion = error.localizedRecoverySuggestion {
            title = suggestion
        }else{
            title = "error"
        }
        if let titles = error.localizedRecoveryOptions {
            btnTitle = titles[0]
        }else{
            btnTitle = "OK"
        }

        let alertView = UIAlertView(title: title, message: message, delegate: nil, cancelButtonTitle: btnTitle)
        alertView.show()
    }
}

実際に動かした、エラーの画面です。
これは、動画を連続でアルバム内に保存しようとした時に出たエラーです。
[書き込みを再試行]が言葉足らず感が否めないですが、これにプラスで文言を付け加えようとすると、自力でローカライズする必要が出てくるので、あえてやりません。

滅多に起きないという前提ですし、雰囲気伝わるのでいいのではないでしょうか。

スクリーンショット_2015_11_11_11_41.png

この設定も忘れずに

ローカライズしたことがあれば分かると思いますが、[Localizations]に追加した言語以外は英語で表示されるのでローカライズしたい言語を追加してください。
OtherViews_と_Piconnect_xcodeproj.png

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした