SwiftUI解码报错No value associated with key CodingKeys问题求助
问题原因
- 字段归属层级错误:
object和has_more都是JSON根层级的字段,并不存在于data数组的子元素中,你在RequestData的自定义解码逻辑里尝试从data子元素中解码这两个不存在的字段,直接触发了keyNotFound错误。 - 类型不匹配:
has_more字段是布尔类型,你代码里写成了String类型,就算字段存在也会解码失败。 - 通用设计逻辑错误:通用Request的设计应该是根据根节点的
object字段判断data数组的元素类型,而非从data元素内部读取类型标识。
修正后可运行代码
let json = """ { "object": "bottle", "has_more": false, "data": [ { "id": "5ffa81e7-1d91-43b5-83cc-9ee1ab634c7b", "name": "14 Hands Hot to Trot White Blend", "price": "$8.99", "image": "https://cdn11.bigcommerce.com/s-7a906/images/stencil/1000x1000/products/8186/10996/14-Hands-Hot-to-Trot-White-Blend__56901.1488985626.jpg?c=2", "sku": "088586004490", "size": "750ML", "origination": "USA, Washington", "varietal": "White Wine", "information": "14 Hands Hot to Trot White Blend", "proof": 121.5, "brand_id": "1", "rating": 1, "review_count": 5 } ] } """ // 通用请求返回枚举,后续新增类型直接加case即可 enum Request: Decodable { case bottle(hasMore: Bool, data: [Bottle]) // 后续扩展其他类型示例:case user(hasMore: Bool, data: [User]) enum CodingKeys: String, CodingKey { case object, hasMore = "has_more", data } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let objectType = try container.decode(String.self, forKey: .object) let hasMore = try container.decode(Bool.self, forKey: .hasMore) switch objectType { case "bottle": let data = try container.decode([Bottle].self, forKey: .data) self = .bottle(hasMore: hasMore, data: data) default: throw DecodingError.dataCorrupted(.init(codingPath: decoder.codingPath, debugDescription: "未知的object类型: \(objectType)")) } } } struct Bottle: Decodable { let id: String let name: String let price: String let image: String let sku: String let size: String let origination: String let varietal: String let information: String let proof: Float let brand_id: String let rating: Int let review_count: Int } // 解码调用 let decoder = JSONDecoder() let requestResult = try decoder.decode(Request.self, from: json.data(using: .utf8)!) switch requestResult { case .bottle(_, let bottles): bottles.forEach { print($0.name) } }
内容的提问来源于stack exchange,提问作者Trenton
相关产品推荐
相关产品推荐

