Swift解码API返回数组对象遇阻,求排查Codable结构体问题
排查Swift Codable解码API JSON的问题
我来帮你梳理下可能导致解码失败的问题点,先把你给出的信息整理清楚:
1. API返回的JSON数据
{ "votes": [ { "votesId": "1", "vote_nb": "6", "current_time": "0", "trend_up": "0", "trend_down": "0", "position_hold": "0", "position_buy": "0", "position_sell": "0" } ] }
2. 你当前的Swift代码片段
struct VoteData : Codable { let votes : [Votes] } struct Votes : Codable { let vote_nb : String } func fetchData(completion: @escaping (VoteDat...
可能的问题及解决方法
问题1:未处理JSON中存在的额外字段
你的Votes结构体只声明了vote_nb,但JSON里的每个投票对象还包含votesId、current_time等其他字段。默认情况下,Codable会要求结构体匹配JSON里的所有字段,缺失字段会直接导致解码失败。
解决方法二选一:
- 补充所有缺失的字段到结构体中:
struct Votes : Codable { let votesId: String let vote_nb: String let current_time: String let trend_up: String let trend_down: String let position_hold: String let position_buy: String let position_sell: String }
- 或者设置解码策略忽略未知字段,在创建
JSONDecoder时添加配置:
let decoder = JSONDecoder() decoder.ignoreUnknownKeys = true // 关键:忽略结构体未声明的字段
问题2:字段命名风格不匹配(可选优化)
JSON里混合了小驼峰(votesId)和蛇形命名(current_time),Swift通常更推荐驼峰命名。你可以通过解码策略自动转换,让代码更符合Swift风格:
struct VoteData : Codable { let votes: [Vote] } struct Vote : Codable { let votesId: String let voteNb: String let currentTime: String let trendUp: String let trendDown: String let positionHold: String let positionBuy: String let positionSell: String } // 解码时设置策略 let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase // 自动将蛇形命名转为驼峰 decoder.ignoreUnknownKeys = true
问题3:fetchData函数的不完整实现
你给出的fetchData代码被截断了,大概率存在回调类型或网络请求逻辑的问题。建议补全函数并添加错误处理,同时打印解码错误信息(这是最快定位问题的方式):
func fetchData(completion: @escaping (VoteData?, Error?) -> Void) { guard let url = URL(string: "你的API地址") else { completion(nil, NSError(domain: "Invalid URL", code: -1, userInfo: nil)) return } URLSession.shared.dataTask(with: url) { data, response, error in if let error = error { completion(nil, error) return } guard let data = data else { completion(nil, NSError(domain: "No data received", code: -2, userInfo: nil)) return } do { let decoder = JSONDecoder() decoder.ignoreUnknownKeys = true let voteData = try decoder.decode(VoteData.self, from: data) completion(voteData, nil) } catch { completion(nil, error) print("解码失败详情:\(error)") // 打印错误,精准定位问题 } }.resume() }
额外排查技巧
解码失败时一定要打印错误信息,错误描述会明确告诉你是字段不匹配、类型不一致还是其他问题,这是最有效的排查手段。
内容的提问来源于stack exchange,提问作者Wizzardzz
相关产品推荐
相关产品推荐

