0Pricing
Swift Academy · 课时

使用 JSONDecoder 解码

将 JSON 数据解析为具有类型的 Swift 值。

使用 JSONDecoder 解码 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。

创建 JSON 解码器

JSONDecoder 可以从 JSON Data 重建 Swift 值。您需要告诉它要生成的类型,并将字节数据交给它。

import Foundation

struct City: Codable {
    var name: String
    var population: Int
}

let json = "{\"name\":\"Oslo\",\"population\":700000}"
let data = json.data(using: .utf8)!
let city = try JSONDecoder().decode(City.self, from: data)
print(city.name, city.population)

使用 .self 传递类型

第一个参数是元类型,写作 MyType.self。它告诉解码器要根据数据构建哪种结构。

import Foundation

struct Flag: Codable { var ok: Bool }

let data = "{\"ok\":true}".data(using: .utf8)!
let result = try JSONDecoder().decode(Flag.self, from: data)
print(result.ok)

解码数组

要解码 JSON 数组,请指定数组类型,例如 [Int].self 或 [MyStruct].self。

import Foundation

let json = "[10, 20, 30]"
let data = json.data(using: .utf8)!
let numbers = try JSONDecoder().decode([Int].self, from: data)
print(numbers.reduce(0, +))

解码嵌套对象

嵌套的 JSON 对象会映射为嵌套的 Codable 结构体。解码器会遍历这棵树,并为您填充每一层。

import Foundation

struct Coord: Codable { var lat: Double; var lon: Double }
struct Place: Codable { var name: String; var coord: Coord }

let json = "{\"name\":\"X\",\"coord\":{\"lat\":1.0,\"lon\":2.0}}"
let p = try JSONDecoder().decode(Place.self, from: json.data(using: .utf8)!)
print(p.coord.lat, p.coord.lon)

捕获解码错误

当数据与类型不匹配时,decode 会抛出错误。将它放在 do/catch 中,可以优雅地处理格式错误的输入。

import Foundation

struct User: Codable { var name: String }

let bad = "{\"wrong\":1}".data(using: .utf8)!
do {
    let u = try JSONDecoder().decode(User.self, from: bad)
    print(u.name)
} catch {
    print("Failed:", error)
}

keyNotFound 错误

一种常见的失败情况是 DecodingError.keyNotFound:当缺少必需的键时就会抛出它。您可以对错误进行模式匹配,准确报告发生了什么问题。

import Foundation

struct User: Codable { var name: String }

let bad = "{}".data(using: .utf8)!
do {
    _ = try JSONDecoder().decode(User.self, from: bad)
} catch let DecodingError.keyNotFound(key, _) {
    print("Missing key:", key.stringValue)
} catch {
    print("Other error:", error)
}

typeMismatch 错误

如果某个值的 JSON 类型不正确,例如预期为 Int 却得到字符串,解码器就会抛出 DecodingError.typeMismatch。

import Foundation

struct Count: Codable { var n: Int }

let bad = "{\"n\":\"oops\"}".data(using: .utf8)!
do {
    _ = try JSONDecoder().decode(Count.self, from: bad)
} catch let DecodingError.typeMismatch(type, _) {
    print("Type mismatch, expected:", type)
} catch {
    print("Other:", error)
}

dataCorrupted 错误

无效的 JSON 语法会引发 DecodingError.dataCorrupted。这通常意味着这些字节根本不是有效的 JSON。

import Foundation

struct User: Codable { var name: String }

let bad = "not json".data(using: .utf8)!
do {
    _ = try JSONDecoder().decode(User.self, from: bad)
} catch is DecodingError {
    print("Decoding failed: data corrupted")
} catch {
    print("Other:", error)
}

解码为可选值

如果某个属性是可选值,缺少对应的键会解码为 nil,而不会抛出错误。这使可选字段能够容忍缺失的数据。

import Foundation

struct Profile: Codable {
    var name: String
    var bio: String?
}

let json = "{\"name\":\"Kai\"}"
let p = try JSONDecoder().decode(Profile.self, from: json.data(using: .utf8)!)
print(p.name, p.bio ?? "no bio")

重复使用解码器

与编码器一样,配置好的 JSONDecoder 可以用于多个数据载荷。保留一个实例,用它解码不同的输入。

import Foundation

struct Word: Codable { var text: String }

let decoder = JSONDecoder()
let inputs = ["{\"text\":\"hi\"}", "{\"text\":\"bye\"}"]
for s in inputs {
    let w = try decoder.decode(Word.self, from: s.data(using: .utf8)!)
    print(w.text)
}

解码、检查并使用

完整流程是:接收 Data,在 do/catch 中将其解码为具有明确类型的值,然后安全地使用这个强类型结果。

import Foundation

struct Weather: Codable {
    var city: String
    var temp: Double
}

let json = "{\"city\":\"Rome\",\"temp\":21.5}"
do {
    let w = try JSONDecoder().decode(Weather.self, from: json.data(using: .utf8)!)
    print("\(w.city): \(w.temp)C")
} catch {
    print("Decode error:", error)
}

快速检查:JSON 解码器

测试您对解码的理解。

回顾:使用 JSON 解码器进行解码

您已经学习了如何从 JSON 重建 Swift 值:

  • decode(MyType.self, from: data) 会生成一个具有明确类型的值。
  • 数组、嵌套对象和可选值都会自动解码。
  • decode 会抛出 DecodingError 的不同情况:keyNotFound、typeMismatch、dataCorrupted 和 valueNotFound。
  • 将调用放在 do/catch 中,以处理格式错误的输入。

常见问题解答

「使用 JSONDecoder 解码」课时是免费的吗?

是的 — 「使用 JSONDecoder 解码」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。

「使用 JSONDecoder 解码」这节课中我会学到什么?

将 JSON 数据解析为具有类型的 Swift 值。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Swift Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「使用 JSONDecoder 解码」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Swift Academy 课中编写并运行代码吗?

能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 遵循 Codable
  2. 使用 JSONEncoder 编码
  3. 使用 JSONDecoder 解码
  4. 处理可选类型与嵌套类型
← 返回 Swift Academy