You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Swift中JSON转换时的Coding Keys缺失错误

问题

通过ViewModel调用API接口获取数据并转换为数组时,JSON转换持续报错。

ViewModel代码

class ViewModel: ObservableObject {
    @Published var courses: [Course] = []
    
    func fetch() {
        guard let url = URL(string: "https://api.spaceflightnewsapi.net/v3/articles") else {
            return
        }
        
        let task = URLSession.shared.dataTask(with: url) { [weak self]data, _, error in
            guard let data = data, error == nil else {
                return
            }
            
            // Convert to JSON
            do {
                let courses = try JSONDecoder().decode([Course].self, from: data)
                DispatchQueue.main.async {
                    self?.courses = courses
                }
            } catch {
                print(error) //---Error Here---
                print("Error with converting to JSON")
            }
        }
        task.resume()
    }
}

Course结构体定义

struct Course: Hashable, Codable {
    let name: String
    let image: String
    let id: Int
    let title: String
    let newsSite: String
    let summary: String
    let publishedAt: String
    let updatedAt: String
    let featured: Bool
    let launches: String
    let events: String
}

报错信息

keyNotFound(CodingKeys(stringValue: "name", intValue: nil), Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: "name", intValue: nil) ("name").", underlyingError: nil))

请问是否在Course结构体中遗漏了某些配置?


解决方案

报错核心原因是Course结构体的字段与API返回的JSON结构不匹配,具体问题和修改方案如下:

  1. 移除不存在的name字段
    API返回的文章数据里没有name这个键,JSONDecoder找不到对应值就会抛出keyNotFound错误,直接删掉这个字段即可。

  2. 修正image字段的键名
    API返回的图片字段键是imageUrl,不是你定义的image,需要把结构体里的image改成imageUrl。

  3. 修正launches和events的类型
    这两个字段在API返回中是数组类型(包含多个对象),不是String。你需要定义对应的子结构体来解析它们,或者如果不需要具体内容,可以用[String: Codable]类型。

修改后的Course结构体及子结构体

struct Course: Hashable, Codable {
    let id: Int
    let title: String
    let newsSite: String
    let summary: String
    let publishedAt: String
    let updatedAt: String
    let featured: Bool
    let imageUrl: String // 修正键名
    let launches: [Launch] // 改为数组类型
    let events: [Event] // 改为数组类型
}

// 解析launches数组的子结构体
struct Launch: Hashable, Codable {
    let id: String
    let provider: String
}

// 解析events数组的子结构体
struct Event: Hashable, Codable {
    let id: String
    let provider: String
}

可选优化

如果不需要解析launches和events的具体内容,也可以把它们定义为[String: Any],但需要手动实现Codable,不如定义子结构体清晰。

修改完成后,重新运行代码,JSON解析就能正常工作了。


内容的提问来源于stack exchange,提问作者Jack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 21:10:38