Swift Codable:使用编码和解码帮助您快速开发iOS应用程序

发布时间:2023-05-19

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(EncodableDecodable),那么这将导致编码 - 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,并且通过相同的方式将其解码回来。