Swift Codable 是什么?
Swift Codable 是苹果推出的用于编码和解码的协议,可以使得我们在 iOS 应用程序开发中更加方便地进行数据的序列化和反序列化。 在前些年,我们需要手动编写大量的代码来实现数据的序列化和反序列化,但是现在使用 Swift Codable 协议可以大大简化这个过程。 让我们来看一下 Swift Codable 的用法:
struct Person: Codable {
var name: String
var age: Int
}
let json = """
{
"name": "Tommy",
"age": 25
}
""".data(using: .utf8)!
let decoder = JSONDecoder()
do {
let person = try decoder.decode(Person.self, from: json)
print(person)
} catch {
print(error)
}
在上面的例子中,我们定义了一个 Person 结构体,并遵守了 Codable 协议。然后我们把一个 JSON 格式的字符串解析成了一个 Person 对象,这是 Swift Codable 的一个非常基础的应用场景。
Codable 的实现原理
在 Swift 中,编码和解码使用的是两个不同的协议:
Encodable
Decodable
这两个协议的定义非常简单:
protocol Encodable {
func encode(to encoder: Encoder) throws
}
protocol Decodable {
init(from decoder: Decoder) throws
}
Encodable
协议中有一个 encode(to:)
方法,用于将对象编码成数据;Decodable
协议中有一个 init(from:)
方法,用于将数据解码成对象。
Swift Codable 的许多魔法都隐藏在其下面实现的附加协议中。它们是:
SingleValueEncodingContainer
SingleValueDecodingContainer
UnkeyedEncodingContainer
UnkeyedDecodingContainer
KeyedEncodingContainer
KeyedDecodingContainer
这个协议家族内部的每个协议都有非常清晰的功能划分,使得 Swift Codable 可以轻易解析 JSON、XML、属性列表和其他格式的数据。
在 Swift Codable 中使用 CodingKeys
当编写代码时,我们经常会需要将结构体中的名称映射到键值对中不同的名称。例如,我们可能有一个 Swift 结构体:
struct Person: Codable {
var firstName: String
var lastName: String
var age: Int
}
但是,我们想要使用 JSON 作为数据传输格式。在此情况下,我们可能需要一个 JSON 表示法:
{
"first_name": "John",
"last_name": "Doe",
"age": 30
}
如果我们只使用 Codable(Encodable
和 Decodable
),那么这将导致编码 - Swift 能够自动识别要使用的数据格式是 JSON,但是由于数据结构中属性和 JSON 键之间的不同,Decodable
(反序列化)会不起作用。
在这种情况下,您可以添加一个名为 CodingKeys
的嵌套枚举,该嵌套枚举遵循 CodingKey
协议(现在请注意编写时编写单词时的意义),如下所示:
struct Person: Codable {
var firstName: String
var lastName: String
var age: Int
enum CodingKeys: String, CodingKey {
case firstName = "first_name"
case lastName = "last_name"
case age
}
}
现在,我们的 Swift 编码器和解码器将知道我们希望使用 "first_name"
键而不是 "firstName"
键来将数据编码为 JSON,并且通过相同的方式将其解码回来。