> For the complete documentation index, see [llms.txt](https://yongpenglovemimi123.gitbook.io/henry/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yongpenglovemimi123.gitbook.io/henry/swift/jsonencode-jsondecode.md).

# JSONEncode JSONDecode

序列化模型到 JSON，和反序列化 JSON 到模型，在 Swift4 之前一直都比较麻烦，所以像一些第三方库就非常的流行，比如 SwiftJSON，HandyJSON 等，例如我们在 Swift3 下，只能使用 JSONSerialization 这个类，进行序列化和反序列化，但是有一个明显的问题没办法解决。

JSONSerialization 无法将 JSON 直接反序列化成模型，只能反序列成字典，数组，String 这种系统内置类型。 也就是为什么，HandyJson 这种第三方库会非常的流行。

例如：

```swift
let json = try? JSONSerialization.jsonObject(with: data, options: []) 
if  let recipe = json as? [String: Any]
{ if  let yield = recipe["yield"] as? Int 
  { recipeObject.yield = yield }
 }
```

## JSONEncode  JSONDecode 的出现

> 在 Swift4 出来之后，系统提供了 Codable 协议 ，JSONEncode，JSONDecode 类型， 解决了反序列化成模型的问题。

下面我们举几个使用例子

#### 1.模型转换成 JSON

例如：

```swift
struct User: Codable {
    var name: String
    var age: String
    var gender: String
}

let user = User(name: "Henry", age: "21", gender: "male")
let encoder = JSONEncoder()
let data = try! encoder.encode(user)
let str = String(data: data, encoding: .utf8)
print("str:\(str)")

// `str:Optional("{\"name\":\"Henry\",\"age\":\"21\",\"gender\":\"male\"}")`
```

#### 2.JSON 转换成模型

例如：

```swift
let userJSONStr = """
{"name":"John","age":"14","gender":"male"}
"""

struct User: Codable {
    var name: String
    var age: String
    var gender: String
}

let decoder = JSONDecoder()
let user = try! decoder.decode(User.self, from: userJSONStr.data(using: .utf8)!)
print("[STRUCT] user.name:\(user.name)")


// [STRUCT] user.name:John
// [CLASS] user.name:John
```

## JSON 反序列化成 Model 的规则

我举了两个例子，图解什么样的数据结构可以映射成功。

例子 1: ![WechatIMG1126.png](https://img.hacpai.com/file/2020/01/WechatIMG1126-c6b777c4.png)

例子 2: 可以看到，很 cool 使用枚举类型来嵌入我们的模型，但是在验证中得出，只要服务器下发的字段，无法匹配上这个枚举，就会导致反序列化失败，整个 Model 无法被反序列化，所以这个还是慎用，如果是你和服务器是严格约定好的，那么没有任何问题。

![WechatIMG1127.png](https://img.hacpai.com/file/2020/01/WechatIMG1127-1677cbf8.png)

通过上图的例子，你可以清楚看到，JSONDecode 是严格按照数据类型来反序列化的，也就是，比如你和服务器订好了，这个字段 A 的类型就是一个 String，但是某一天你改了类型，改成了 Int，那么不好意思，这个反序列化会失败，整个 Model 都不能被解析出来，但是比如服务器去掉了这个字段，我只需要把模型中的类型，换成可选类型，还是可以映射成功的。

最后 这篇文章只是一个最基础的讲解，反序列化的能与不能没，如果想要具体查看详细的使用，更多用法，可以去这里 <https://www.raywenderlich.com/3418439-encoding-and-decoding-in-swift> 。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yongpenglovemimi123.gitbook.io/henry/swift/jsonencode-jsondecode.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
