在之前的版本中,Swift中Error与OC中NSError没有关系。但是现在两者可以互相强转。
我们看看两者的区别:Error是一个实现Error协议的枚举或者结构体,对外能够获取的具体信息只有rawValue。但是我们知道NSError是有UserInfo和domain的。
先来看看Swift中Error
枚举Error:
代码语言:javascript复制enum LoginError: Error {
case LoginSucess
case LoginPasswordWrong
case LoginMobileInvalid
}
基本的error处理:
//注意catch中的error是抛出的Error对象,这个对象没有通过var error:Error创建,在catch的大括号里直接就能拿到,如果想要取得错误信息,直接处理error就可以
代码语言:javascript复制 // 模拟登录接口
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:
代码语言:javascript复制struct XMLParsingError: Error {
enum ErrorKind {
case invalidCharacter
case mismatchedTag
case internalError
}
let line: Int
let column: Int
let kind: ErrorKind
}
结构体Error的基本处理:
代码语言:javascript复制 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的:
代码语言:javascript复制throw NSError(code: HomeworkError.dogAteIt.rawValue,
domain: HomeworkError._domain,
userInfo: [ NSLocalizedDescriptionKey : "the dog ate it" ])
如果OC中的NSError桥接到Swift中,变成Error类型,那么获取NSError中的UserInfo信息也变成了一件头疼的事情,比如AVError:
代码语言:javascript复制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就增加了更多的信息。
代码语言:javascript复制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中也有对应的三个属性:
代码语言:javascript复制@property (readonly, copy) NSString *localizedDescription;
@property (nullable, readonly, copy) NSString *localizedFailureReason;
@property (nullable, readonly, copy) NSString *localizedRecoverySuggestion;
CustomNSError
CustomNSError 用来桥接原来NSError中的code、domain、UserInfo。
代码语言:javascript复制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