如何在 Swift 中使用 Codable 和 JSONSerialization 解析JSON数据

原文:How To Parse JSON in Swift Using Codable and JSONSerialization

在 Swift 中对 JSON、Dictionary 和 Array 进行编码和解码。

这篇文章提供了以下示例代码,用于在不使用第三方依赖包或框架的情况下在 Swift 中对 JSON 编码和解码。

使用 JSONDecoder 将 JSON 解码为 Struct

Decodable 协议允许使用 JSONDecoder 类将 JSON 编码的数据解析为 Swift 结构体。

swift 复制代码
/// 候选人模型
struct Candidate: Decodable {
    var name: String
    var skill: String
}

let jsonObject = "{\"name\":\"Taylor\",\"skill\":\"Swift\"}"
let jsonObjectData = jsonObject.data(using: .utf8)!

// 将 json data 解码为 Candidate 结构体
let candidate = try? JSONDecoder().decode(Candidate.self, from: jsonObjectData)

// 访问解码后的 Candidate 结构体属性
candidate?.name // Taylor
candidate?.skill // Swift

⬇️ 代码示例:加载 Bundle 包中的 json 文件,并使用 JSONDecoder 解码为结构体

swift 复制代码
import Foundation

// 电影
struct Film: Codable {
    let title: String
    let year: String
    let poster: String
    let plot: String
    var isExpanded: Bool

    // 自定义 init 方法,设置 isExpanded 默认值为 false
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        title = try container.decode(String.self, forKey: .title)
        year = try container.decode(String.self, forKey: .year)
        poster = try container.decode(String.self, forKey: .poster)
        plot = try container.decode(String.self, forKey: .plot)

        isExpanded = false
    }
}

struct Auteurs: Codable {
    let auteurs: [Auteur]
}

// 导演
struct Auteur: Codable {
    let name: String
    let bio: String
    let source: String
    let image: String
    var films: [Film]

    static func auteursFromBundle() -> [Auteur] {
        var auteurs: [Auteur] = []
        // 加载 Bundle 包中的 auteurs.json 文件,并使用 JSONDecoder 解码。
        guard let url = Bundle.main.url(forResource: "auteurs", withExtension: "json") else {
            fatalError("Error: Unable to find specified file!")
        }

        do {
            let data = try Data(contentsOf: url)
            let json = try JSONDecoder().decode(Auteurs.self, from: data)
            auteurs = json.auteurs
        } catch {
            fatalError("Error occured during parsing, \(error)")
        }

        return auteurs
    }
}

使用 JSONEncoder 将 Struct 编码为 JSON

要将 Swift 结构体编码为 JSON,设置结构体遵守 Codable 协议。

swift 复制代码
/// 候选人模型
struct Candidate: Codable {
    var name: String
    var skill: String
}

let candidate = Candidate(
    name: "Taylor",
    skill: "Swift"
)

// 将 candidate data 编码为 JSON。期待编码后的数据:
// {"name":"Taylor","skill":"Swift"}
let candidateData = try? JSONEncoder().encode(candidate)

将 JSON 数据解析为 Swift Dictionary 和 NSDictionary

在 Swift 中解析 JSON 的另一种方法是使用 JSONSerialization.jsonObject(with:options:),它可以解析 JSON 并转换为 Swift DictionaryNSDictionary

swift 复制代码
let jsonDict = "{\"key\":\"value\"}"
let jsonDictData = jsonDict.data(using: .utf8)!

let object = try? JSONSerialization.jsonObject(with: jsonDictData, options: [])

// Cast to a Swift Dictionary
let dict = object as? [AnyHashable:Any]

// Cast to an NSDictionary
let nsDict = object as? NSDictionary

将 JSON 数据解析为 Swift Array 和 NSArray

JSONSerialization.jsonObject(with:options:) 也可用于解析 JSON 并转换为 Swift ArrayNSArray

swift 复制代码
let jsonArray = "[1,2,3,4,5]"
let jsonArrayData = jsonArray.data(using: .utf8)!

let object = try? JSONSerialization.jsonObject(with: jsonArrayData, options: []) as? [Any]

// Cast to a Swift Array
let array = object as? [Any]

// Cast to a NSArray
let nsArray = object as? NSArray

将 NSDictionary 编码为 JSON

使用 JSONSerialization.data(withJSONObject:options:)NSDictionary 编码为 JSON 数据。

swift 复制代码
let nsDictionary = NSDictionary(dictionary: [
    "key": "value",
    "key2": "value2"
])

let nsDictionaryData = try? JSONSerialization.data(withJSONObject: nsDictionary, options: [])

// Expected encoded data:
// {"key":"value","key2":"value2"}

传递 JSONSerialization 写入选项标志 .prettyPrinted 以输出带有缩进和换行格式的 JSON 编码的 NSDictionary 数据。

swift 复制代码
let prettyNSDictionaryData = try? JSONSerialization.data(
    withJSONObject: nsDictionary,
    options: [.prettyPrinted]
)

// Expected encoded data:
// {
//     "key": "value",
//     "key2": "value2"
// }

将 NSArray 编码为 JSON

类似地,可以使用 JSONSerialization.data(withJSONObject:options:)NSArray 编码为 JSON 数据。

swift 复制代码
let nsArray = NSArray(array: [1,2,3,4,5])

let nsArrayData = try? JSONSerialization.data(
    withJSONObject: nsArray,
    options: []
)

// Expected encoded data:
// [1,2,3,4,5]

传递 JSONSerialization 写入选项标志 .prettyPrinted 以输出带有缩进和换行格式的 JSON 编码的 NSArray 数据。

swift 复制代码
let prettyNSArrayData = try? JSONSerialization.data(
    withJSONObject: nsArray,
    options: [.prettyPrinted]
)

// Expected encoded data:
// [
//     1,
//     2,
//     3,
//     4,
//     5
// ]

为什么不使用 SwiftyJSON 和 Cocoapods 在 Swift 中解析 JSON?

除了 Apple 提供的 JSONSerialization 等类所允许的范围之外,许多应用程序不需要复杂的 JSON 操作。通过使用 Apple 提供的类实现 JSON 解析和编码,开发人员可以:

  • 通过删除 SwiftyJSON 等第三方依赖来简化代码库;
  • 减少应用程序的二进制包大小;
  • 降低与第三方依赖相关的风险;

Swift 中的 JSON 编码和解码

仅此而已!使用 JSONSerializationJSONDecoderJSONEncoder,您可以在 Swift 中使用 JSON,而无需添加任何外部依赖。

相关推荐
营赢盈英10 小时前
Why is OpenAI image generation Api returning 400 bad request in Unity?
ai·json·openai api·post·unitywebrequest·unitygameengine
一晌小贪欢11 小时前
Python基础知识——字典排序(不断补充)
python·json·python基础·字典·字典排序·python学习
浮游本尊14 小时前
深入了解package.json文件
json
小学导航员16 小时前
notepad++的json查看
json·notepad++
Rattenking1 天前
node - npm常用命令和package.json说明
前端·npm·json
Swift社区2 天前
Apple 新品发布会亮点有哪些 | Swift 周报 issue 61
ios·swiftui·swift
Snowbowღ2 天前
OpenAI / GPT-4o:Python 返回结构化 / JSON 输出
python·json·openai·api·gpt-4o·pydantic·结构化输出
林戈的IT生涯2 天前
MySQL5.7中增加的JSON特性的处理方法JSON_EXTRACT和JSON_ARRAY_APPEND以及MYSQL中JSON操作的方法大全
json·mysql5.7·json特性·json_extract·mysql中json操作方法
敲代码不忘补水2 天前
Python 项目实践:简单的计算器
开发语言·python·json·项目实践
亚林瓜子3 天前
Jackson注解屏蔽某些字段读取权限
spring·json·jackson