Codable: 实现在 swift 中像 js 那样使用 JSON

官方文档,关于 Codable 实现:https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types

js 一样,iOS 11 之后,swift 也可以方便的使用 json 来传递数据了。

要想使用 json, 你操作的类需要实现 Codable 接口
Foundation 中的所有类都已经实现了 Cadable,所以如果你的实体中没有自定义的一些数据类型,都可以直接使用 JSON

js 一样,swift 中的 json 也有:

  • JSONEncoder 将数据转成 json 数据
  • JOSNDecoderjson 数据,转为可用的你需要的数据类型

看下面的 PlayGround 例子便知道如何使用了

由对象转字符串

import Foundation

struct Person: Codable {
    var name: String
    var age: Int
    var intro: String
}

let kyle = Person(name: "Kyle", age: 29, intro: "A web developer")
let tina = Person(name: "Tina", age: 26, intro: "A teacher for English")
let persons = [kyle, tina]

// Encode
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted // setup formatter
let jsonData = try encoder.encode(persons)
print(String(data: jsonData, encoding: .utf8)!)


// Decode
let decoder = JSONDecoder()
// 注意 decode() 中的第一个参数
let people = try decoder.decode(Array<Person>.self, from: jsonData)
print(people[0].name)

输出如下:

[
  {
    "name" : "Kyle",
    "age" : 29,
    "intro" : "A web developer"
  },
  {
    "name" : "Tina",
    "age" : 26,
    "intro" : "A teacher for English"
  }
]
Kyle

由字符串转对象

import Foundation

struct Person: Codable {
    let name: String
    let age: Int
    let intro: String
}

let jsonString = """
[
    {
        "name": "Kyle",
        "age": 27,
        "intro": "A font-end enginer",
        "location": "Jinan"
    },
    {
        "name": "Tina",
        "age": 26,
        "intro": "A UI enginer",
        "location": "Jinan"
    }
]
"""

// 1. 先从字符串转为 Data
let jsonData = jsonString.data(using: .utf8)!

// 2. 再用 Data 转成对应的对象
let decoder = JSONDecoder()
let persons = try decoder.decode(Array<Person>.self, from: jsonData)

print(type(of: persons[0]))

cadable.png

对象名与 json 名不一致时

有些时候,对象声明中的变量名跟json中的键名不一致,如 nameEn 在 json 中需要为 json_en
只需要在对象声明中用 CodingKeys 声明要转成的字符串即可,如下:不需要转的就不需要写 = 后面的东西了

//
//  Person.swift
//  CustomisedViews
//
//  Created by Kyle on 2020/3/2.
//  Copyright © 2020 KyleBing. All rights reserved.
//

import Foundation

struct Person: Codable {
    var id: String
    var name: String
    var nameEn: String
    var nickName: String
    var perk: String
    var motto: String
    var health: String
    var sanity: String
    var hunger: String
    var version: String
    var pic: String
    
        enum CodingKeys: String, CodingKey {
        case nameEn = "name_en"
        case nickName = "nick_name"
        // 下面这些变量名不需要变,就只写 case 就可以了
        // 要把对象中的变量全部遍历出来,不然会出错
            case id
            case name
            case perk
            case motto
            case health
            case sanity
            case hunger
            case version
            case pic
        }
}

KyleBing
659 声望18 粉丝

前端,喜欢 Javascript scss,喜欢做一些实用的小工具