swift3.0之后的Error处理

在之前的版本中,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

时间: 2024-10-06 14:55:58

swift3.0之后的Error处理的相关文章

swift3.0:CoreData的使用

一.介绍 CoreData不像slqite3那样编写代码繁琐,同时避免了使用了SQL语句的麻烦,也可以回避使用C语言的语法,降低了iOS开发的技术门槛. CoreData可降低开发成本,提高代码质量.它是一个完全面向对象的API,能够合理管理内存,负责在数据库中存储数据,底层也是由类似 于SQL的技术实现的.CoreData是持久化存储的最佳方式,数据最终的存储类型可以是SQLite数据库.XML.二进制.内存或自定义数据类型 它和SQLite的区别是:只能取出整个实体记录,然后分离,之后才能得

Swift2.3适配Swift3.0时出现的各种问题

昨晚上一波手贱把我的小5s升到iOS10.如此配套的话,Xcode7.3升级Xcode8.1看来也是势在必行了.公司程序是Swift2.3的,出于对苹果的恐惧迟迟不敢升级.但丑媳妇儿总要见公婆,借这个机会,也趁双休时间,做一下适配好了. 首先,强调一点.做好备份!做好备份!做好备份!重要的事情说三遍. 1.关于使用的Swift代码库的问题 这是我最心力交瘁的一个问题. 项目中使用了Swift的几个开源框架,SwiftHTTP.SwiftyJSON.KingFisher等等.我的项目并没有使用Co

(细节控)swift3.0与融云IMKIT开发问题(一部分) override func onSelectedTableRow Method does not override any method from its superclass

原官网文档方案如下,在swift3.0的情况下出现 override func onSelectedTableRow  Method does not override any method from its superclass 这是因为swift3.0 有很多变更,需要更换下onSelectedTableRow参数. //重写RCConversationListViewController的onSelectedTableRow事件 override func onSelectedTableR

Swift2.3 --> Swift3.0 的变化

Swift3.0语法变化 首先和大家分享一下学习新语法的技巧: 用Xcode8打开自己的Swift2.3的项目,选择Edit->Convert->To Current Swift Syntax- 让Xcode帮我们把Swift2.3的代码转换为Swift3.0. 手动调出Xcode自动转换Swift2.3 到 Swift3.0 弹出语言版本选择界面,选择Covert to Swift3,Next:  进入选择模块界面: 选择模块界面 建议只选择自己创建的模块,第三方框架的模块最好不要使用Xco

使用 swift3.0高仿新浪微博

项目地址:https://github.com/SummerHH/swift3.0WeBo 使用 swift3.0 高仿微博,目前以实现的功能有,添加访客视图,用户信息授权,首页数据展示(支持正文中连接匹配,@匹配)支持照片浏览,大图浏览,保存图片到相册本地, 实现发布微博,发微博添加照片,发送Emoticon表情等功能, 先看下项目整体框架 项目使用 MVC 框架,但是在写的过程中也用到了 MVVM设计模式

使用的一些支持swift3.0的开源库

#解决键盘弹起遮挡工具 pod 'IQKeyboardManagerSwift', '~>4.0.6' #多种类型弹出框 pod 'SCLAlertView', :git => 'https://github.com/vikmeup/SCLAlertView-Swift' # Alamofire 网络库 (4.1.0最低支持iOS8.0,4.0最低支持iOS9.0) pod 'Alamofire', '~> 4.0' # swift解析json库 pod 'SwiftyJSON', :g

Swift3.0 函数闭包与OC Block

刚接触Swift,如有不对的点,欢迎指正.转载请说明出处 Swift中定义一个基本函数 //定义一个函数,接收一个字符串,返回一个String类型的值 func test(name:String) -> String { return ("输出了\(name)") } //通用形式 func name(parameters) -> return type { function body } Swift 中基本的闭包函数与OC中Block的相似点 带参闭包 //OC中Bloc

swift3.0 coredata 的使用

//swift3.0在语法上有很大的改变,以简单的增删改查为例,如下: //User类如下: import Foundation import CoreData extension User { @nonobjc public class func fetchRequest() -> NSFetchRequest<User> { return NSFetchRequest<User>(entityName: "User"); } @NSManaged pu

iOS 日期处理 (Swift3.0 NSDate)

处理日期的常见情景 NSDate -> String & String -> NSDate 日期比较 日期计算(基于参考日期 +/- 一定时间) 计算日期间的差异 拆解NSDate对象(分解成year/month/day/hour/minute/second 等) NSDate相关类 NSDate DateFormatter DateComponents DateComponentFormatter Calendar Date structure: Swift3.0中引入了Date s