Swift 4 Codable协议 - 基本用法

Swift 4新增了Codable协议,它是一个组合协议,包含Encodable和Decodable两个协议。代码定义如下:

/// A type that can convert itself into and out of an external representation.
public typealias Codable = Decodable & Encodable

/// A type that can encode itself to an external representation.
public protocol Encodable {
  public func encode(to encoder: Encoder) throws
}
 
/// A type that can decode itself from an external representation.
public protocol Decodable {
  public init(from decoder: Decoder) throws
}

Encodable协议定义了encode(to encoder: )函数,它用于编码我们的数据。
Decodable协议定义了init(from decoder: Decoder )函数,用于解析数据。

Codable协议最常用的场景就是JSON数据和模型的转换。

基本用法

Codable有一个默认的实现,在很多情况下使用默认实现就可以很简便完成JSON数据与模型的转换。

如以下示例

JSON结构:


{
  "name":  "张三",
  "age": 10
}

对象模型:

struct Student: Codable {
  var name: String
  var age: Int
}

解码

我们使用JSONDecoder只需要很少的代码就可以把JSON数据解析为Student对象。

let jsonData = jsonString.data(encoding: .utf8)!
let decoder = JSONDecoder()
let student = try! decoder.decode(Student.self, for: jsonData)

注意:示例里JSON数据的键和Student结构体的属性名是相同的。

编码

相反,我们也可以使用JSONEncoder来把Student对象编码为JSON数据。

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try! encoder.encode(student)
print(String(data: data, encoding: .utf8)!)

其中encoder.outputFormatting = .prettyPrinted是为了让JSON数据输出的结构更可读。

输出如下:

{
  "name":  "张三",
  "age": 10
}

适配键

在上面的例子里,JSON数据的键和Student结构体的属性名是相同的。如果JSON的键与结构体属性不一致,我们可以使用CodingKey来把两者关联起来,适配JSON的键。

JSON

{
  "name":  "张三",
  "age": 10,
  "residential_address":"广东省深圳市南山区xxx"
}

Student

struct Student: Codable {
  var name: String
  var age: Int
  var residentialAddress: String

  enum CodingKeys: String, CodeingKey {
    case name
    case age
    case residentialAddress = "residential_address"
  }

}

在此例子里,residential_address为新增的键,而Student结构体里的residentialAddress为驼峰式命名。所以我们需要对redidentital_address和residentialAddress做关联。

关联代码定义在CodingKeys枚举里。

数组

let decoder = JSONDecoder()
let students = try decoder.decode([Student].self, from: data)

使用Codable协议,处理数组也很简单,只要Array<T>里的T是继承于Codable协议的,那么Array<T>也是可以根据Codable协议解编码的。

嵌套

对于包含嵌套的结构体,只要嵌套的结构体是继承于Codable协议,那么整个结构体也是可以根据Codable协议解编码。

如下面例子里JSON新增了scores属性用于存放每一科目对应的分数。

JSON

{
  "name":  "张三",
  "age": 10,
  "scores":[
    {
      "subject": "Chinese",
      "score": 100
    },
    {
      "subject": "Math",
      "score": 100
    },
    {
      "subject": "English",
      "score": 100
    }
  ]
}

SubjectScore结构体

struct SubjectScore: Codable {
  var subject: String
  var score: Int
}

Student结构体

struct Student: Codable {
  var name: String
  var age: Int
  var scores: [SubjectScore]
}

这个示例用SubjectScore结构体表示JSON里scores数组里单一科目的分数。它继承与Codable,Student也继承与Codable,所以Student也是可解析的。

总结

这些例子里我们都是使用了Codable的默认实现来解码/编码来做JSON数据与模型之间的转换。与Swift3 转换JSON数据不同,使用Codable的默认实现不需要我们手动解析JSON数据。

当然,如果我们也可以编写自己的Codable实现,以完成更高级的转换。

版权声明:著作权归作者所有。

相关推荐

Swift 4:KeyPath

Swift 4对KeyPath做了很大的改进。改进后的为类型安全的KeyPath。Swift 2的KeyPath示例class Person: NSObject {   var name: String = ""   init(name: 

Angular 5:HttpClient的基本用法

Angular 4.3引入了新的用于http请求的接口HttpClient。它旨在替换之前版本的接口Http。有以下新特性:对响应的body做类型检查默认返回的是JSON对象,不再需要使用json()显式解析返回的数据支持拦截器支持进度事件请求后验证和基于刷新的测试框架安装HttpClientModuleHttpClient属于@angular/common/http包的模块HttpCl

Swift 4的KVO(Key Value Observation)用法

KVO 是 Objective-C 对观察者模式的实现。当被观察对象的某个属性发生更改时,观察者对象会获得通知。KVO实现依赖于Objective-C的Runtime,所以Swift需要使用@objc暴露api给Objective C。Swift目前没有内置原生实现的值观察系统,Swift 4的KVO使用dynamic属性来实现。被观察的类clas

Swift日期和字符串互相转换(Swift 3/Swift 4)

Swift随着版本的升级,日期类都会有一点变化。所以各个版本的Swift日期和字符串的转换有所不同。Swift 4String转换为Datevar dateString = "2017-11-17" var dateFormatter = DateFormatter() // dateFormat

使用Swift 3/Swift 4扫描二维码

iOS的AVFoundation内置了对二维码和条形码扫描的支持。使用AVFoundation扫描二维码的功能需要几件事:创建AVCaptureSession,用于捕获二维码创建预览捕获二维码成功后,委派回调来处理二维码的meta信息下面的例子是基于UIViewController开发的扫描二维码Controller,使用AVCaptureMetadataOutputObjectsDelegate

Swift3/Swift4 转换Html为纯文本

Swift 3或者Swift 4 添加String扩展,把Html字符串转换为纯文本Xcode 9 beta • Swift 4extension String {     var html2AttributedString: NSAttr