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

相关推荐
惜.己2 小时前
使用python读取json数据,简单的处理成元组数组
开发语言·python·测试工具·json
stoneSkySpace15 小时前
set、map 比数组,json 对象的性能更好原因分析
json
Keya1 天前
lipo 命令行指南
ios·xcode·swift
zhangmeng1 天前
SwiftUI中如何实现子视图向父视图传递数据?
ios·swiftui·swift
Saafo1 天前
迁移至 Swift Actors
ios·swift
Rabbb1 天前
C# JSON 反序列化时,忽略转换失败的属性 JTokenSafeToExtensions
后端·c#·json
代码的余温2 天前
XML vs JSON:核心区别与最佳选择
xml·服务器·json
前端 贾公子2 天前
exports使用 package.json字段控制如何访问你的 npm 包
前端·npm·json
杂雾无尘2 天前
告别构建错误, iOS 开发架构难题全面解析, 避免 CPU 架构陷阱
ios·swift·客户端
三千花灯2 天前
jmeter提取接口返回值,对比去重
jmeter·json