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

Swift中如何解码嵌套响应数据?需解析响应里的items字段

嘿,我来帮你搞定Swift里的JSON解码问题!咱们一步步来,先解决items字段的解析,再详细讲讲嵌套结构的解码方法。

1. 先对齐你的现有代码与响应数据

首先我先模拟一套常见的代码场景(如果和你的实际情况有出入,你可以调整结构体字段或响应结构):

请求函数示例

func fetchCities(completion: @escaping (Result<[City], Error>) -> Void) {
    guard let url = URL(string: "https://your-api-endpoint.com/cities") else {
        completion(.failure(NSError(domain: "Invalid URL", code: -1, userInfo: nil)))
        return
    }
    
    URLSession.shared.dataTask(with: url) { data, response, error in
        if let error = error {
            completion(.failure(error))
            return
        }
        
        guard let data = data else {
            completion(.failure(NSError(domain: "No data received", code: -2, userInfo: nil)))
            return
        }
        
        // 这里就是你遇到解码问题的核心区域
        do {
            // 原来的错误写法:直接解码成[City],但API返回的是包含items的顶层对象
            let cities = try JSONDecoder().decode([City].self, from: data)
            completion(.success(cities))
        } catch {
            completion(.failure(error))
            print("解码失败:\(error)")
        }
    }.resume()
}

City结构体示例

struct City: Codable {
    let id: Int
    let name: String
    let country: String
}

典型API响应数据(包含items字段)

{
"status": "success",
"message": "Fetched cities successfully",
"items": [
{"id": 1, "name": "Tokyo", "country": "Japan"},
{"id": 2, "name": "Paris", "country": "France"}
]
}

2. 解决items字段的解析问题

问题本质是:API返回的根结构不是直接的[City]数组,而是一个包含items数组的顶层对象。所以我们需要先定义一个匹配顶层结构的响应结构体,再从中提取items数据。

步骤1:定义顶层响应结构体

// 完全匹配API返回的完整JSON结构
struct CityResponse: Codable {
    let status: String
    let message: String
    let items: [City] // 这里对应响应里的items字段,类型就是你的City数组
}

步骤2:修改解码逻辑

把原来的解码代码改成先解码顶层响应,再取出items:

do {
    let response = try JSONDecoder().decode(CityResponse.self, from: data)
    completion(.success(response.items)) // 直接返回items里的城市数组
} catch {
    completion(.failure(error))
    print("解码失败:\(error)")
}

这样就能正确解析出items字段里的城市数据了!

3. 嵌套结构的解码方法详解

如果你的API响应有更深层次的嵌套(比如每个City里还有coordinates子对象),处理思路也很清晰:

示例嵌套响应数据

{
"items": [
{
"id": 1,
"name": "Tokyo",
"country": "Japan",
"coordinates": {
"latitude": 35.6762,
"longitude": 139.6503
}
}
]
}

步骤1:定义嵌套的子结构体

先给嵌套的coordinates单独定义一个符合Codable的结构体:

struct Coordinates: Codable {
    let latitude: Double
    let longitude: Double
}

步骤2:修改City结构体,加入嵌套字段

直接把嵌套结构体作为City的一个字段即可:

struct City: Codable {
    let id: Int
    let name: String
    let country: String
    let coordinates: Coordinates // 嵌套的结构体字段
}

步骤3:正常解码即可

Codable协议会自动处理嵌套结构的编码和解码,只要你的结构体字段名和JSON键名完全匹配,直接用JSONDecoder解码就行,不需要额外操作。

特殊情况:字段名不匹配怎么办?

如果JSON里的键名和你Swift结构体的字段名不一致(比如JSON用lat,你想叫latitude),可以用CodingKeys自定义映射:

struct Coordinates: Codable {
    let latitude: Double
    let longitude: Double
    
    // 自定义编码/解码的键映射
    enum CodingKeys: String, CodingKey {
        case latitude = "lat"
        case longitude = "lon"
    }
}
4. 常见解码错误排查小技巧

如果还是解码失败,优先检查这几点:

  • 字段名是否完全匹配:Swift默认是驼峰命名,JSON如果是蛇形命名,可以设置JSONDecoder的keyDecodingStrategy = .convertFromSnakeCase自动转换
  • 字段类型是否一致:比如JSON里是数字,你结构体里用了String就会报错
  • 是否有可选字段:如果JSON里某个字段可能不存在,要把结构体对应字段设为可选类型(比如let name: String?)

举个自动转蛇形的例子:

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase // 自动把snake_case转成camelCase
let response = try decoder.decode(CityResponse.self, from: data)

内容的提问来源于stack exchange,提问作者Aidogdy Shahyrov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:06:15