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

Swift中JSONDecoder解析特定JSON失败,求解析方案与错误排查

Swift JSONDecoder解析问题解决方案

1. 是否可以使用JSONDecoder解析该特定JSON?

可以,但需要处理类型不匹配问题:API返回的result是字符串类型("true"),而你的结构体中定义的result是Bool类型,默认的JSONDecoder无法直接完成这种跨类型转换,需要添加自定义处理逻辑。

2. 是否需要修改我的Codable类以实现正确解析?

需要修改,推荐两种可行方案:

方案一:自定义解码逻辑(规范做法)

在ActionClock结构体中实现自定义的解码初始化方法,手动将字符串类型的result转换为Bool:

struct ActionClock: Codable {
    var result: Bool? = false
    var message: String? = "invalid"
    
    enum CodingKeys: String, CodingKey {
        case result, message
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        // 解析result:先取字符串,再转换为Bool
        if let resultStr = try container.decodeIfPresent(String.self, forKey: .result) {
            result = resultStr.lowercased() == "true"
        }
        
        // 解析message,保留默认值
        message = try container.decodeIfPresent(String.self, forKey: .message) ?? "invalid"
    }
}

方案二:临时调整属性类型(快速调试)

将result的类型改为String?,使用时通过计算属性转换为Bool:

struct ActionClock: Codable {
    var result: String? = "false"
    var message: String? = "invalid"
    
    // 计算属性,方便直接获取Bool值
    var isResultTrue: Bool {
        return result?.lowercased() == "true"
    }
}

3. 添加try...catch查看解码异常

将原代码中的try?替换为do-catch块,捕获并打印详细错误信息,就能直接定位解析失败的原因:

func loadTime() {
    guard let url = URL(string: "https://actionmobile.app/GetTime") else {
        print("Invalid URL")
        return
    }
    let request = URLRequest(url: url)

    URLSession.shared.dataTask(with: request) { data, response, error in
        if let data = data {
            print("data: \(data) \(Date())")
            do {
                let response = try JSONDecoder().decode(ActionClock.self, from: data)
                print("is this called?")
                DispatchQueue.main.async {
                    self.atime = response
                    print("in LOADTIME")
                }
                print("response: \(response)")
            } catch {
                // 打印错误信息,包括本地化描述和详细错误
                print("解码失败:\(error.localizedDescription)")
                print("错误详情:\(error)")
            }
        } else {
            print("I failed")
        }
    }.resume()
}

原代码用try?会静默忽略错误,改用do-catch后,你会看到类似Expected Bool value but found string instead.的错误提示,直接点明类型不匹配的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 16:05:24