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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏编程之旅

iOS开发——自主设计日志系统

好像很久没有写有关iOS的文章了,其实iOS的开发一直都是在进行的,但是最近有需求拓宽知识的宽度,所以一直在接触别的知识,当然啦,移动端开发并不能丢下。

18020
来自专栏進无尽的文章

RunTime 之其他实践运用

有关Runtime的知识总结,我本来想集中写成一篇文章的,但是最后发现实在是太长,而且不利于阅读,最后分成了如下几篇:

11830
来自专栏陈满iOS

iOS·NSObject的两种含义:类与协议

iOS开发中,苹果提供的一些系统类都属于NSObject的子类,例如UIColor类的定义如下所示。

17650
来自专栏个人分享

Netty的TCP粘包/拆包(源码二)

假设客户端分别发送了两个数据包D1和D2给服务器,由于服务器端一次读取到的字节数是不确定的,所以可能发生四种情况:

23340
来自专栏青玉伏案

Objective-C中的单例模式

    ​    ​单例模式算是设计模式中比较简单的一种吧,设计模式不是只针对某种编程语言,在C++, Java, PHP等其他OOP语言也有设计模式,笔者初接...

21970
来自专栏陈满iOS

iOS·数据结构选型:在某数据结构中避免重复字符串元素(NSArray,NSSet,NSDictionary)

解析某博客或者书籍网站数据时:已知它的书籍首页URL地址,这个首页含有它的书籍目录及其章节的链接,APP想拉取它的目录节点,然而,该目录页面里面的章节可能有重复...

13320
来自专栏IT进修之路

原 荐 JAVA懒开发:FreeMarker

23660
来自专栏逆向技术

内核开发知识第一讲.内核中的数据类型.重要数据结构.常用内核API函数.

  在内核中.程序的编写不能简单的用基本数据类型了. 因为操作系统不同.很有可能造成数据类型的长度不一.而产生重大问题.所以在内核中.

19220
来自专栏xx_Cc的学习总结专栏

iOS-单例模式写一次就够了

25550
来自专栏岑志军的专栏

KVO详解及底层实现

17020

扫码关注云+社区

领取腾讯云代金券