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
相关产品推荐
相关产品推荐

