You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何解码嵌套JSON结构中的User对象?

如何解码嵌套结构的JSON获取User对象

你遇到的问题很典型——当API的JSON结构从扁平改成嵌套层级后,直接用原来的解码方式肯定不行,因为你不能直接对Data类型做下标访问(data是二进制数据,不是已经解析好的字典)。下面是具体的解决步骤:

第一步:定义匹配新JSON结构的嵌套模型

你需要创建和新JSON层级对应的结构体,让JSONDecoder能正确解析每一层的数据:

// 保持你原来的User结构体不变
struct User: Codable {
    let id: Int
    let email: String
}

// 新增对应notifications的结构体
struct Notification: Codable {
    let id: String
    let notifiableType: String
    
    // 处理JSON中的蛇形命名,映射成Swift的驼峰命名
    enum CodingKeys: String, CodingKey {
        case id
        case notifiableType = "notifiable_type"
    }
}

// 定义包含user和notifications的容器结构体
struct DataContainer: Codable {
    let user: User
    let notifications: [Notification]
}

// 顶层的响应结构体,对应最外层的data字段
struct ApiResponse: Codable {
    let data: DataContainer
}

第二步:修改解码逻辑

现在你需要先解码顶层的ApiResponse,再逐层取出里面的User对象:

let httpURL = "https://dev.test/api/user"
guard let url = URL(string: httpURL) else {
    print("无效的URL")
    return
}

var request = URLRequest(url: url)
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
    guard let data = data else {
        print("没有获取到数据")
        return
    }
    
    do {
        // 先解码顶层的ApiResponse
        let apiResponse = try JSONDecoder().decode(ApiResponse.self, from: data)
        // 从嵌套结构中取出User对象
        let user = apiResponse.data.user
        
        DispatchQueue.main.async {
            print(user.email)
            // 如果需要notifications,也可以直接访问
            print(apiResponse.data.notifications)
        }
    } catch let jsonErr {
        print("解码失败:", jsonErr)
    }
}
task.resume()

为什么之前的写法不对?

你尝试的data.data.user和data["data"]["user"]都是错误的,因为:

  • data是Data类型(二进制数据),不是字典或者自定义模型,所以没有data属性,也不能用下标访问
  • 必须先通过JSONDecoder把二进制数据解码成对应层级的结构体,才能逐层访问里面的属性

这样调整后,就能正确解析嵌套的JSON结构,拿到你需要的User对象了。

内容的提问来源于stack exchange,提问作者Juan Rangel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 06:31:07