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

Swift中如何解码JSON至结构体时忽略双方非共有的字段?

Swift Codable:仅解码JSON与结构体共有的字段

问题场景

将以下JSON解码到Device结构体时出现异常:

错误JSON(注意语法问题:Model行末尾缺少逗号):

{
    "SerialNumber": "123",
    "Model": "iPhone14"
    "Brand": "Apple"
}

原始Swift结构体:

struct Device : Codable, Identifiable {
    var id = UUID().uuidString
    let SerialNumber : String
    let Model : String
    let Brand : String
}

最初的解决方法是手动添加CodingKeys枚举,指定要解码的字段(因为id不存在于JSON中):

private enum CodingKeys: String, CodingKey {
    case SerialNumber, Model, Brand
}

但这种方式有明显弊端:后端移除某个JSON字段时,必须同步修改CodingKeys;同时也不确定如何处理JSON包含结构体没有的额外字段的情况。核心需求是:能否让Codable自动仅解码JSON与结构体共有的字段,无需手动维护CodingKeys?


解决方案

1. 先修正JSON语法错误

首先要解决原始JSON的语法问题:"Model": "iPhone14"行末尾缺少逗号,这是导致解码失败的直接原因之一,修正后的JSON应为:

{
    "SerialNumber": "123",
    "Model": "iPhone14",
    "Brand": "Apple"
}

2. 自动忽略JSON中的额外字段

Swift的Codable默认行为就是自动忽略JSON中结构体没有的字段,无需任何额外配置。比如如果JSON新增了"Color": "Red"字段,解码到Device结构体时会直接跳过该字段,不会引发异常。

3. 允许JSON缺失结构体字段(无需修改CodingKeys)

如果后端可能移除某个字段,只需将结构体中对应的字段改为可选类型,或者给字段设置默认值,这样即使JSON中没有该字段,解码也能成功:

方式一:使用可选类型

struct Device: Codable, Identifiable {
    var id = UUID().uuidString
    let serialNumber: String?
    let model: String?
    let brand: String?
}

注:这里遵循Swift命名规范用小驼峰,配合JSONDecoder的keyDecodingStrategy自动映射JSON的大驼峰字段:

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromPascalCase
let device = try decoder.decode(Device.self, from: jsonData)

方式二:给字段设置默认值

如果不希望用可选类型,可以给字段设置默认值,这样JSON缺失该字段时会使用默认值:

struct Device: Codable, Identifiable {
    var id = UUID().uuidString
    let serialNumber: String = ""
    let model: String = ""
    let brand: String = ""
}

4. 处理自定义默认字段(如id)

结构体中的id字段有默认值,Codable会自动忽略对该字段的解码,无需手动写CodingKeys。只要字段有明确的默认值(或者是var类型且初始化时赋值),解码过程就不会尝试从JSON中读取该字段。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 20:33:20