web-dev-qa-db-ja.com

Swift 3のカスタムエラーのlocalizedDescriptionをオーバーライドする方法?

エラープロトコル 1つのみ プロパティのlocalizedDescription。 NSObjectとErrorから継承したカスタムオブジェクトを作成しようとしましたが、localizedDescriptionをオーバーライドできません。どうやってやるの?

このコードでは、カスタムの説明を取得できません。

class MyError: NSObject, Error {
    var desc = ""
    init(str: String) {
        desc = str
    }
    override var description: String {
        get {
            return "MyError: \(desc)"
        }
    }
   var localizedDescription: String {
        get {
            return self.description
        }
    }
}

func test_my_code() {
    let error = MyError(str: "my test string")
    let x = error as Error
    print(x.localizedDescription)
}

関数「test_my_code」を呼び出すと、予期しない結果が得られます:「操作を完了できませんでした...」。

結果「MyError:my test string」を取得するにはどうすればよいですか?

20

新しいエラーブリッジング機能に関するドキュメントは現在まだ十分に明確ではないため、この回答には近い将来更新が必要になる可能性がありますが、 SE-0112 および latest SwiftソースコードLocalizedErrorではなくErrorを使用し、errorDescriptionを実装する必要がある場合があります。

class MyError: NSObject, LocalizedError {
    var desc = ""
    init(str: String) {
        desc = str
    }
    override var description: String {
        get {
            return "MyError: \(desc)"
        }
    }
    //You need to implement `errorDescription`, not `localizedDescription`.
    var errorDescription: String? {
        get {
            return self.description
        }
    }
}

func test_my_code() {
    let error = MyError(str: "my test string")
    let x = error as Error
    print(x.localizedDescription)
}
test_my_code() //->MyError: my test string

LocalizedErrorを使用する以外に、このデフォルトの実装は機能します:

(NSError.Swift、上記のリンク)

public extension Error {
    /// Retrieve the localized description for this error.
    var localizedDescription: String {
        return NSError(domain: _domain, code: _code, userInfo: nil).localizedDescription
    }
}

Swiftが_domainまたは_codeErrorに準拠する任意の型から定義する方法は少し複雑ですが、NSErrorは、ドメインとコードの不明な組み合わせに対して「操作を完了できませんでした...」を生成します。

43
OOPer

カスタムタイプがプロトコルCustomStringConvertibleに準拠し、ローカライズされたdescriptionを提供する場合、次のLocalizedErrorの拡張が役立つ場合があります。

extension LocalizedError where Self: CustomStringConvertible {

   var errorDescription: String? {
      return description
   }
}

サンプルコード:

class MyError: LocalizedError, CustomStringConvertible {

   let desc: String

   init(str: String) {
      desc = str
   }

   var description: String {
      let format = NSLocalizedString("Operation error: %@", comment: "Error description")
      return String.localizedStringWithFormat(format, desc)
   }
}


let error = MyError(str: "my test string")
let x = error as Error
print(x.localizedDescription) // Prints "Operation error: my test string"
print(String(describing: x))  // Prints "Operation error: my test string"
9
Vlad