swift3.0之后的Error處理


在之前的版本中,Swift中Error與OC中NSError沒有關系。但是現在兩者可以互相強轉。

我們看看兩者的區別:Error是一個實現Error協議的枚舉或者結構體,對外能夠獲取的具體信息只有rawValue。但是我們知道NSError是有UserInfo和domain的。

先來看看Swift中Error

枚舉Error:

enum LoginError: Error {
    case LoginSucess
    case LoginPasswordWrong
    case LoginMobileInvalid
}

基本的error處理:

//注意catch中的error是拋出的Error對象,這個對象沒有通過var error:Error創建,在catch的大括號里直接就能拿到,如果想要取得錯誤信息,直接處理error就可以
  // 模擬登錄接口
    func loginMethod(nick: String,password: String) throws {
        guard !nick.isEmpty else {
            throw LoginError.LoginMobileInvalid
        }
        guard !password.isEmpty else {
            throw LoginError.LoginPasswordWrong
        }
        print("登錄成功")
    }
// 購物接口,購物之前要先登錄 func pay() throws { do { try loginMethod(nick: "", password: "wangdachui") } catch LoginError.LoginMobileInvalid { print("昵稱為空") } catch LoginError.LoginPasswordWrong { print("密碼錯誤") } catch { print("登錄成功") }
 
    }

 

結構體Error:

struct XMLParsingError: Error {
 enum ErrorKind {
     case invalidCharacter
     case mismatchedTag
     case internalError
 }

 let line: Int
 let column: Int
 let kind: ErrorKind
}

結構體Error的基本處理:

 func parse(_ source: String) throws -> XMLDoc {
     // ...
     throw XMLParsingError(line: 19, column: 5, kind: .mismatchedTag)
     // ...
 }

function:

 do {
     let xmlDoc = try parse(myXMLData)
 } catch let e as XMLParsingError {
     print("Parsing error: \(e.kind) [\(e.line):\(e.column)]")
 } catch {
     print("Other error: \(error)")
 }
 // Prints "Parsing error: mismatchedTag [19:5]"

 

但是我們知道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。


參考資料:http://www.jianshu.com/p/a36047852ccc

參考資料:http://www.jianshu.com/p/911c7a2805d5


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM