如何在 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,而无需添加任何外部依赖。

相关推荐
疯狂SQL21 小时前
手写高性能在线 JSON 工具|Web Worker 工程化打包 + 语法自动修复 + 多语言代码生成实战
typescript·json·next.js·web worker·前端性能优化·esbuild·源码实战
sweet丶3 天前
Swift 元编程-Macro
swift
影寂ldy6 天前
WinForm PictureBox控件 + ImageList组件 完整笔记
开发语言·笔记·swift
terry6006 天前
5G视频短信服务商选型全攻略:通道资源、架构能力与成本评估2026最新标准
大数据·人工智能·5g·json·asp.net·信息与通信·数据库架构
前网易架构师-高司机6 天前
带标注的辣椒病叶数据集,识别率95.9%,可识别三种病害和健康叶子,9916张图,支持yolo,coco json,voc xml,文末有模型训练代码
yolo·json·数据集·病害·叶病·病叶·辣椒
PixelBai6 天前
JSON扁平化使用教程:从入门到精通
json
Deepzz7 天前
macOS 上调教第三方鼠标的一些经验:从滚动顺滑到输入法自动切换
macos·swift·鼠标
渔舟唱晚,雁阵惊寒7 天前
CSDN博客内容丢失如何恢复?
json
衣乌安、7 天前
JSON-RPC协议
网络协议·rpc·json