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

相关推荐
葬歌倾城19 小时前
JSON的缩进格式方式和紧凑格式方式
c#·json
旷世奇才李先生1 天前
Swift 安装使用教程
开发语言·ios·swift
火车叨位去19491 天前
Java中的JSON序列化和反序列化
json
测试杂货铺2 天前
Jmeter(六):json断言元件,jmeter参数化实现
jmeter·json
Daniel_Coder2 天前
Xcode 中常用图片格式详解
ios·xcode·swift
帅次2 天前
Objective-C面向对象编程:类、对象、方法详解(保姆级教程)
flutter·macos·ios·objective-c·iphone·swift·safari
专注VB编程开发20年2 天前
C#,VB.NET从JSON数据里提取数组中的对象节点值
c#·json·.net
RyanGo2 天前
iOS断点下载
ios·swift
杂雾无尘2 天前
掌握生死时速:苹果应用加急审核全攻略!
ios·swift·apple
HarderCoder2 天前
Swift 6.2 中的 `@concurrent`
ios·swift