Ben*_* Lu 57 error-handling swift swift2
在Swift 2.0中NSError符合ErrorType协议.
对于自定义错误,我们可以为某些情况指定关联对象,如下所示.
enum LifeError: ErrorType {
case BeBorn
case LostJob(job: String)
case GetCaughtByWife(wife: String)
...
}
Run Code Online (Sandbox Code Playgroud)
我们可以轻松地做到以下几点:
do {
try haveAffairWith(otherPerson)
} catch LifeError.GetCaughtByWife(let wife) {
...
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我们希望它作为一个传递到其他地方NSError,它就会丢失它的关联对象信息.
println("\(LifeError.GetCaughtByWife("Name") as NSError)")
Run Code Online (Sandbox Code Playgroud)
打印:
Error Domain=... Code=1 "The operation couldn't be completed". (... error 1)
Run Code Online (Sandbox Code Playgroud)
它userInfo是nil.
我wife和哪里有联系ErrorType?
Igo*_*ilo 43
Xcode 8中的新功能:CustomNSError 协议.
enum LifeError: CustomNSError {
case beBorn
case lostJob(job: String)
case getCaughtByWife(wife: String)
static var errorDomain: String {
return "LifeError"
}
var errorCode: Int {
switch self {
case .beBorn:
return 0
case .lostJob(_):
return 1
case .getCaughtByWife(_):
return 2
}
}
var errorUserInfo: [String : AnyObject] {
switch self {
case .beBorn:
return [:]
case .lostJob(let job):
return ["Job": job]
case .getCaughtByWife(let wife):
return ["Wife": wife]
}
}
}
Run Code Online (Sandbox Code Playgroud)
ilu*_*pra 23
一个ErrorType不能真正被转换为NSError,你必须采取相关的数据,并将其打包成一个NSError自己.
do {
try haveAffairWith(otherPerson)
} catch LifeError.GetCaughtByWife(let wife) {
throw NSError(domain:LifeErrorDomain code:-1 userInfo:
[NSLocalizedDescriptionKey:"You cheated on \(wife)")
}
Run Code Online (Sandbox Code Playgroud)
编辑:实际上你可以从中执行ErrorType转换NSError,但是NSError你从默认实现得到的是非常原始的.我在我的应用程序中正在做的是挂钩应用程序:willPresentError:在我的应用程序委托中并使用自定义类来读取我的应用程序ErrorType并装饰NSErrors以返回.
ork*_*den 14
NSError在每个catch块中创建一个可以导致大量复制和粘贴以将您的自定义转换ErrorType为NSError.我把它抽象出类似@powertoold.
protocol CustomErrorConvertible {
func userInfo() -> Dictionary<String,String>?
func errorDomain() -> String
func errorCode() -> Int
}
Run Code Online (Sandbox Code Playgroud)
这个扩展可以包含代码,这是LifeError我们已经拥有的代码以及我们可能创建的其他自定义错误类型.
extension CustomErrorConvertible {
func error() -> NSError {
return NSError(domain: self.errorDomain(), code: self.errorCode(), userInfo: self.userInfo())
}
}
Run Code Online (Sandbox Code Playgroud)
关闭实施!
enum LifeError: ErrorType, CustomErrorConvertible {
case BeBorn
case LostJob(job: String)
case GetCaughtByPolice(police: String)
func errorDomain() -> String {
return "LifeErrorDomain"
}
func userInfo() -> Dictionary<String,String>? {
var userInfo:Dictionary<String,String>?
if let errorString = errorDescription() {
userInfo = [NSLocalizedDescriptionKey: errorString]
}
return userInfo
}
func errorDescription() -> String? {
var errorString:String?
switch self {
case .LostJob(let job):
errorString = "fired as " + job
case .GetCaughtByPolice(let cops):
errorString = "arrested by " + cops
default:
break;
}
return errorString
}
func errorCode() -> Int {
switch self {
case .BeBorn:
return 1
case .LostJob(_):
return -9000
case .GetCaughtByPolice(_):
return 50
}
}
}
Run Code Online (Sandbox Code Playgroud)
这就是如何使用它.
func lifeErrorThrow() throws {
throw LifeError.LostJob(job: "L33tHax0r")
}
do {
try lifeErrorThrow()
}
catch LifeError.BeBorn {
print("vala morgulis")
}
catch let myerr as LifeError {
let error = myerr.error()
print(error)
}
Run Code Online (Sandbox Code Playgroud)
您可以轻松地将某些功能,如func userInfo() -> Dictionary<String,String>?从LifeError到extension CustomErrorConvertible或不同的分机.
不像上面那样对错误代码进行硬编码,而是枚举可能更可取.
enum LifeError:Int {
case Born
case LostJob
}
Run Code Online (Sandbox Code Playgroud)
我对这个问题的解决方案是创建一个符合Int,ErrorType的枚举:
enum AppError: Int, ErrorType {
case UserNotLoggedIn
case InternetUnavailable
}
Run Code Online (Sandbox Code Playgroud)
然后扩展枚举以符合CustomStringConvertible和一个名为CustomErrorConvertible的自定义协议:
extension AppError: CustomStringConvertible, CustomErrorConvertible
protocol CustomErrorConvertible {
var error: NSError { get }
}
Run Code Online (Sandbox Code Playgroud)
对于描述和错误,我打开了AppError.例:
Description: switch self {
case .UserNotLoggedIn: return NSLocalizedString("ErrorUserNotLoggedIn", comment: "User not logged into cloud account.")
case .InternetUnavailable: return NSLocalizedString("ErrorInternetUnavailable", comment: "Internet connection not available.")
}
Error: switch self {
case .UserNotLoggedIn: errorCode = UserNotLoggedIn.rawValue; errorDescription = UserNotLoggedIn.description
case .InternetUnavailable: errorCode = InternetUnavailable.rawValue; errorDescription = InternetUnavailable.description
}
Run Code Online (Sandbox Code Playgroud)
然后我编写了自己的NSError:
return NSError(domain:NSBundle.mainBundle().bundleIdentifier!, code:errorCode, userInfo:[NSLocalizedDescriptionKey: errorDescription])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19591 次 |
| 最近记录: |