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

相关推荐
denggun1234514 小时前
结构化并发(Structured Concurrency)
开发语言·ios·swift
杀神lwz15 小时前
Java Json压缩工具类
java·json
fl17683117 小时前
智慧医疗X光牙齿疾病识别分割数据集labelme格式13887张31类别
json
denggun1234518 小时前
Swift6.0为主版本小版本迭代
ios·swift
denggun1234519 小时前
Swift 版本历年更新记录(核心里程碑 + 关键特性)
开发语言·ios·swift
denggun1234520 小时前
基于 async/await 的 Swift 并发模型重构
ios·swift
leluckys1 天前
swift- Swift中常见的面试题
开发语言·汇编·swift
BUG_MeDe1 天前
json格式字符串解析的简单使用 libjson-c
c语言·开发语言·json
泉木2 天前
Swift 从入门到精通-第四篇
swift
泉木2 天前
Swift 从入门到精通-终篇
swift