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

Swift处理HTTP请求返回的数组响应体问题求助

Swift解析HTTP数组响应到Codable结构体的解决方案

一、先确认你的Codable结构体定义正确

首先要保证结构体的属性和返回的JSON键名、类型完全匹配,必要时用CodingKeys做映射(如果JSON键和Swift属性名不一致)。

假设你的PHP接口返回的JSON是Chapter对象的数组,示例JSON如下:

[
  {
    "id": 1,
    "title": "入门指南",
    "media_list": [
      {
        "media_id": 1001,
        "url": "https://example.com/video1.mp4",
        "duration": 180
      }
    ]
  }
]

对应的Codable结构体定义:

struct Chapter: Codable {
    let id: Int
    let title: String
    let mediaList: [Media]
    
    // 如果JSON键和Swift属性名不同,用CodingKeys映射
    enum CodingKeys: String, CodingKey {
        case id, title
        case mediaList = "media_list"
    }
    
    struct Media: Codable {
        let mediaId: Int
        let url: String
        let duration: Int
        
        enum CodingKeys: String, CodingKey {
            case mediaId = "media_id"
            case url, duration
        }
    }
}

二、用URLSession+JSONDecoder完成请求与解析

替代JSONSerialization,直接用JSONDecoder将响应数据解析为[Chapter]类型,代码更简洁且类型安全:

// 定义请求方法,用闭包返回结果
func fetchChapters(completion: @escaping (Result<[Chapter], Error>) -> Void) {
    // 替换成你的PHP接口地址
    guard let requestUrl = URL(string: "https://your-domain.com/get-chapters.php") else {
        completion(.failure(NSError(domain: "InvalidURL", code: -1, userInfo: [NSLocalizedDescriptionKey: "URL格式错误"])))
        return
    }
    
    let task = URLSession.shared.dataTask(with: requestUrl) { data, _, error in
        // 处理网络请求错误
        if let requestError = error {
            completion(.failure(requestError))
            return
        }
        
        // 确保响应有数据
        guard let responseData = data else {
            completion(.failure(NSError(domain: "NoData", code: -2, userInfo: [NSLocalizedDescriptionKey: "接口未返回数据"])))
            return
        }
        
        do {
            // 核心:将数据解析为Chapter数组
            let chapters = try JSONDecoder().decode([Chapter].self, from: responseData)
            completion(.success(chapters))
        } catch let decodeError {
            // 解析失败时,打印完整错误信息方便排查
            print("解析错误详情:\(decodeError)")
            completion(.failure(decodeError))
        }
    }
    
    task.resume()
}

三、调用请求方法并处理结果

// 在合适的地方调用(比如ViewController的viewDidLoad)
fetchChapters { result in
    DispatchQueue.main.async {
        switch result {
        case .success(let chapters):
            // 拿到解析后的章节数组,做UI渲染等操作
            print("成功获取\(chapters.count)个章节")
            for chapter in chapters {
                print("章节标题:\(chapter.title),包含\(chapter.mediaList.count)个媒体资源")
                for media in chapter.mediaList {
                    print("媒体ID:\(media.mediaId),地址:\(media.url)")
                }
            }
        case .failure(let error):
            // 处理错误(比如弹出提示)
            print("请求失败:\(error.localizedDescription)")
        }
    }
}

四、常见问题排查

  • JSON格式不匹配:检查接口返回的JSON是否是标准数组格式(外层是[]),避免多余逗号、单引号等语法错误。
  • 解析报错:打印decodeError的完整信息,Codable会明确提示哪个键不匹配、类型错误(比如JSON是字符串但Swift定义成Int)。
  • 外层有包装对象:如果PHP返回的是带状态码的包装JSON(比如{"code":200,"data":[...]}),需要额外定义外层结构体:
struct ChapterResponse: Codable {
    let code: Int
    let data: [Chapter]
}

解析时改为try JSONDecoder().decode(ChapterResponse.self, from: responseData),再取response.data得到章节数组。

内容的提问来源于stack exchange,提问作者Edgar M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 06:05:23