Combine框架解析API返回JSON报CodingKeys对应键不存在问题求助
问题根因与解决方案
1. 可选字段解码逻辑错误
你当前代码中存在大量声明为可选类型的属性,却使用强制解码逻辑的问题,这是解码报错的核心原因:
UserLoginResponse里currentTime是String?可选类型,但你在自定义init中使用的是try container.decode(String.self, forKey: .currentTime),如果返回数据中不存在current_time字段,哪怕属性声明为可选,也会直接抛出keyNotFound错误。LoginedInUserInfo中声明为可选的lastName、email、birthDate等属性,全部使用了try container.decode强制解码,只要返回的字段缺失就会触发解码失败。
修复方案:所有可选属性使用 decodeIfPresent 方法解码:
// UserLoginResponse init 中修改currentTime解码 currentTime = try container.decodeIfPresent(String.self, forKey: .currentTime) // LoginedInUserInfo 中所有可选属性都改成decodeIfPresent,例如: lastName = try container.decodeIfPresent(String.self, forKey: .lastName) email = try container.decodeIfPresent(String.self, forKey: .email) // 其余可选属性同理修改即可
2. 确认网络返回的原始数据结构
你本地硬编码的JSON可以解码成功,但网络请求失败,大概率是实际接口返回的结构和你预期的不一致:
在 tryMap 块中增加原始数据打印,确认返回内容是否符合预期:
.tryMap { (data: Data, response: URLResponse) in guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { throw URLError(.badServerResponse) } // 增加打印,查看实际返回的JSON内容 if let rawJson = String(data: data, encoding: .utf8) { print("原始接口返回:\(rawJson)") } return data }
常见的不一致场景包括:接口外层额外包裹了其他结构、字段名拼写大小写错误、返回空数据等。
3. 可选优化:简化冗余模型层
你当前的 LoggedInUserData 仅用来包裹 user_data 字段,属于冗余结构,可以直接去掉,在 UserLoginResponse 中直接解码嵌套结构,减少出错概率。
内容的提问来源于stack exchange,提问作者user7167475
相关产品推荐
相关产品推荐

