Swift Codable解析API响应keyNotFound报错的解决方案咨询
解决Codable解析API响应时的
keyNotFound错误 看起来你遇到的问题核心是没有定义匹配整个API响应结构的顶层Codable类型,让我帮你一步步解决:
错误原因拆解
你的错误提示显示在data数组的第0个元素里找不到event_id,但你的JSON里明明存在这个字段——问题出在你直接尝试把整个API响应解析成[Events]或者Events类型,可实际上整个API响应是一个包含status、success、data等字段的顶层对象,data才是你需要的事件数组。解码器在顶层对象里找不到event_id这个key,所以抛出了错误。
解决方案
我们需要定义两个Codable结构体:一个匹配顶层API响应,另一个匹配单个事件的数据结构。而且Codable会自动帮我们生成编解码逻辑,不需要手动实现encode(to:)和init(from:)方法(除非有特殊需求)。
1. 定义正确的Codable模型
// 单个事件的模型,用Swift风格的驼峰命名,通过CodingKeys映射JSON的蛇形命名 struct Event: Codable { let eventId: String let eventName: String let eventDesc: String let fromDate: String let toDate: String let barId: String let barNames: String let barIds: String let offerImage: String let fromTime: String let toTime: String enum CodingKeys: String, CodingKey { case eventId = "event_id" case eventName = "event_name" case eventDesc = "event_desc" case fromDate = "from_date" case toDate = "to_date" case barId = "bar_id" case barNames = "bar_names" case barIds = "bar_ids" case offerImage = "offer_image" case fromTime = "from_time" case toTime = "to_time" } } // 匹配整个API响应的顶层模型 struct EventResponse: Codable { let status: Int let message: String let success: Int let data: [Event] let errorDev: String enum CodingKeys: String, CodingKey { case status, message, success, data case errorDev = "error_dev" } }
2. 正确解析API响应
解析时要把整个响应解析成EventResponse类型,再从中取出data数组:
// 假设你已经获取到API返回的Data对象(apiData) do { let decoder = JSONDecoder() // 可选优化:自动转换蛇形命名到驼峰,省去手动写CodingKeys的步骤 // decoder.keyDecodingStrategy = .convertFromSnakeCase let response = try decoder.decode(EventResponse.self, from: apiData) let events = response.data // 这就是你需要的事件数组 // 在这里处理events数据 } catch { print("解析失败:\(error.localizedDescription)") }
额外优化提示
如果你不想手动写CodingKeys,可以利用JSONDecoder的keyDecodingStrategy自动将JSON的蛇形命名转换为Swift的驼峰命名,这样Event结构体可以直接用驼峰命名,完全省去定义CodingKeys的步骤:
let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase // 简化后的Event结构体 struct Event: Codable { let eventId: String let eventName: String let eventDesc: String let fromDate: String let toDate: String let barId: String let barNames: String let barIds: String let offerImage: String let fromTime: String let toTime: String }
内容的提问来源于stack exchange,提问作者Pradumna Patil
相关产品推荐
相关产品推荐

