JSONDecoder无法解码API返回数据的问题排查求助
解决Swift JSONDecoder解码API数据失败问题
核心问题分析
你的解码失败主要有两个原因:
- 字段名不匹配:API返回的JSON中数组字段是
"data",但你的Response结构体用的是verses,JSONDecoder无法自动映射。 - 额外字段未处理:
Verse中的id是你本地生成的UUID,JSON中不存在该字段,默认Codable会尝试解码这个不存在的字段导致失败。
修改后的完整代码
1. 修正Response结构体
添加CodingKeys将JSON的"data"字段映射到结构体的verses属性:
struct Response: Codable { var verses: [Verse] enum CodingKeys: String, CodingKey { case verses = "data" } }
2. 修正Verse结构体
自定义CodingKeys,排除本地生成的id字段:
struct Verse: Codable, Identifiable { var id = UUID() var book_id: String var book_name: String var book_name_alt: String var chapter: Int var chapter_alt: String var verse_start: Int var verse_start_alt: String var verse_end: Int var verse_end_alt: String var verse_text: String enum CodingKeys: String, CodingKey { case book_id, book_name, book_name_alt, chapter, chapter_alt, verse_start, verse_start_alt, verse_end, verse_end_alt, verse_text } }
3. 优化解码函数
替换try?为try,捕获并打印具体错误信息,方便后续调试:
func getText() async { let urlString = "..." guard let url = URL(string: urlString) else { print("无效URL") return } var request = URLRequest(url: url) request.setValue("...", forHTTPHeaderField: "key") request.setValue("...", forHTTPHeaderField: "v") do { let (data, _) = try await URLSession.shared.data(for: request) let decodedResponse = try JSONDecoder().decode(Response.self, from: data) verses = decodedResponse.verses print("解码成功,共\(verses.count)条经文") } catch { print("解码失败:\(error.localizedDescription)") print("错误详情:\(error)") } }
其他说明
- 不需要使用
unkeyedContainer,因为返回的JSON结构是明确的键值对嵌套数组,不属于无键数组类型。 - 如果你后续需要给
Verse的id指定自定义逻辑(比如用verse_start作为id),可以直接修改id的赋值逻辑,无需调整CodingKeys。
内容的提问来源于stack exchange,提问作者tryingtocode
相关产品推荐
相关产品推荐

