> 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> 。
