Skip to main content

Codable

note

Codeable其实就是Ecodable和Decodable两个协议的组合。

本身的作用一般用来自动进行JSON/XML或者其他的数据和Swift类之间的互相转化。

Encodable 这个协议用在那些需要被编码的类型上。如果遵守了这个协议,并且这个类的所有属性都是 Encodable 的, 编译器就会自动的生成相关的实现。如果不是,或者说你需要自定义一些东西,就需要自己实现了。

Decodable这个协议跟 Encodable 相反,它表示那些能够被解档的类型。跟 Encodable 一样,编译器也会自动为你生成相关的实现,前提是所有属性都是Decodable 的.

这两个协议的实现都很简单,内部都只有一个方法

public protocol Encodable {
func encode(to encoder: Encoder) throws
}
public protocol Decodable {
init(from decoder: Decoder) throws
}

普通的Codable

class User: ObservableObject, Codable{
var name = "Paul Hudsonn"
}

Codable嵌套

struct Response: Codable {
var results: [Result]
}

struct Result: Codable {
var trackId: Int
var trackName: String
var collectionName: String
}

Codable结合@Published

自动解析的同时又能够保持数据的全局共享。

@Publish注解会给属性增加很多的方法,给属性增加@Publish的同时并不会自动给其所属的类也增加@Publish,此时实现Codable除了增加注解之外,还需要手动去实现Codable

  1. 给属性增加@Publush注解
@Published var name = "Paul Hudsonn"
  1. 增加CodingKey作为Codable的Key
enum CodingKeys: CodingKey {
case name
}
  1. 增加init方法,注意这个方法要加上required前缀表示必须。
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
}
  1. 增加encode方法
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
}

实例

class User: ObservableObject, Codable{
enum CodingKeys: CodingKey {
case name
}
@Published var name = "Paul Hudsonn"
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
}
}