Swift 3必看:Error與NSError的關係

weixin_33860722發表於2016-12-29

在學習Swift 3的過程中整理了一些筆記,如果想看其他相關文章可前往《Swift 3必看》系列目錄

在之前的版本中,Swift中Error與OC中NSError的關係就像上海的南京路與南京的上海路關係一樣,那就是沒有關係。
我們先來看兩者的區別。
Error是一個實現ErrorProtocol列舉,對外能夠獲取的具體資訊只有rawValue。

enum HomeworkError : Int, Error {
  case forgotten
  case lost
  case dogAteIt
}

但是我們知道NSError是有UserInfo和domain的:

throw NSError(code: HomeworkError.dogAteIt.rawValue,
              domain: HomeworkError._domain,
              userInfo: [ NSLocalizedDescriptionKey : "the dog ate it" ])

如果OC中的NSError橋接到Swift中,變成Error型別,那麼獲取NSError中的UserInfo資訊也變成了一件頭疼的事情,比如AVError:

catch let error as NSError where error._domain == AVFoundationErrorDomain 
&& error._code == AVFoundationErrorDomain.diskFull.rawValue {
  // okay: userInfo is finally accessible, but still weakly typed
}

很顯然,解決方式就是提供一個方式可以讓這兩個型別可以無損的轉換。

LocalizedError

增加了一個LocalizedError協議。這個協議增加了errorDescription屬性。如果Error同時實現這個協議,相比原來只有rawValue就增加了更多的資訊。

extension HomeworkError : LocalizedError {
  var errorDescription: String? {
    switch self {
    case .forgotten: return NSLocalizedString("I forgot it")
    case .lost: return NSLocalizedString("I lost it")
    case .dogAteIt: return NSLocalizedString("The dog ate it")
    }
  }
}

這個協議同時還有三個屬性:failureReason、helpAnchor、recoverySuggestion。

在NSError中也有對應的三個屬性:

@property (readonly, copy) NSString *localizedDescription;

@property (nullable, readonly, copy) NSString *localizedFailureReason;

@property (nullable, readonly, copy) NSString *localizedRecoverySuggestion;

CustomNSError

CustomNSError 用來橋接原來NSError中的code、domain、UserInfo。

public protocol CustomNSError : Error {

    /// The domain of the error.
    public static var errorDomain: String { get }

    /// The error code within the given domain.
    public var errorCode: Int { get }

    /// The user-info dictionary.
    public var errorUserInfo: [String : Any] { get }
}

如果想讓我們的自定義Error可以轉成NSError,實現CustomNSError就可以完整的as成NSError。

RecoverableError

這次還給Error增加了RecoverableError協議。用來提示使用者可以通過什麼樣的方式來處理這個Error。

歡迎關注我的微博:@沒故事的卓同學
相關連結:
SE-0112:Improved NSError Bridging

相關文章