swift3.0之後的Error處理
阿新 • • 發佈:2017-08-24
www. 基本 nullable property desc 協議 finally ring inter
在之前的版本中,Swift中Error與OC中NSError沒有關系。但是現在兩者可以互相強轉。
我們先來看兩者的區別。
Error是一個實現Error協議的枚舉,對外能夠獲取的具體信息只有rawValue。(也可以是實現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
swift3.0之後的Error處理