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

Swift中适配新API响应结构的Decodable模型修改方案咨询

修改Decodable模型适配新API响应结构

没问题,我来帮你调整代码适配新的API响应结构。首先咱们得先理清新响应的层级:现在整个响应外层多了isSucceed状态字段,实际的请假数据被嵌套在singleData对象里,而且原来的数字字段现在变成了字符串类型(比如"457"而不是457.0)。咱们分三步修改:

1. 创建顶层响应模型

首先需要一个新的模型来匹配外层的响应结构,把原来的Leave作为它的嵌套属性:

struct LeaveResponse: Decodable {
    let isSucceed: Bool
    let singleData: Leave
}

2. 更新Leave模型

接下来要修改原有的Leave模型,主要做两件事:

  • 更新CodingKeys匹配新的字段名(sicilNo和yillikIzin)
  • 自定义解码逻辑,把API返回的字符串类型数字转换成原来的Double类型,保证后续使用逻辑不用大改

修改后的Leave模型代码:

struct Leave: Decodable, Identifiable {
    var id: Double? { return registerNumber }
    let registerNumber: Double
    let annualLeave: Double
    
    enum CodingKeys: String, CodingKey {
        case registerNumber = "sicilNo"
        case annualLeave = "yillikIzin"
    }
    
    // 自定义解码处理字符串转数字
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        // 处理sicilNo字段:先解码字符串,再转成Double
        let sicilNoString = try container.decode(String.self, forKey: .registerNumber)
        guard let sicilNo = Double(sicilNoString) else {
            throw DecodingError.dataCorruptedError(
                forKey: .registerNumber,
                in: container,
                debugDescription: "无法将sicilNo字符串转换为Double类型"
            )
        }
        self.registerNumber = sicilNo
        
        // 处理yillikIzin字段:同样的字符串转Double逻辑
        let yillikIzinString = try container.decode(String.self, forKey: .annualLeave)
        guard let yillikIzin = Double(yillikIzinString) else {
            throw DecodingError.dataCorruptedError(
                forKey: .annualLeave,
                in: container,
                debugDescription: "无法将yillikIzin字符串转换为Double类型"
            )
        }
        self.annualLeave = yillikIzin
    }
}

3. 调整网络请求的解码逻辑

最后修改请求里的解码部分,现在要先解码顶层的LeaveResponse,再取出里面的singleData传给completion:

let task = session.dataTask(with: request) { (data, response, error) in
    if error == nil {
        let decoder = JSONDecoder()
        if let safeData = data {
            do {
                // 先解码整个响应模型
                let apiResponse = try decoder.decode(LeaveResponse.self, from: safeData)
                // 取出嵌套的Leave对象
                let result = apiResponse.singleData
                DispatchQueue.main.async {
                    completion(result)
                }
            } catch {
                print(error)
            }
        }
    }
}
task.resume()

这样修改后,就能像之前一样正常获取并解析数据了,而且保持了原来Leave模型的类型结构,后续使用registerNumber和annualLeave的地方不用额外修改。

内容的提问来源于stack exchange,提问作者Mert Kökşal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 23:47:38