Swift中JSON转Struct问题:修复格式错误并验证结构体准确性
解决JSON语法错误与Swift结构体适配问题
我来帮你一步步搞定这两个问题:
一、修复JSON的语法问题
你遇到的“缺少逗号”提示,根源是JSON数组的语法错误:原JSON里plans被定义为数组([]),但数组内部直接写了"full_plan": {...}这种对象键值对格式——数组只能存放值(比如对象、字符串等),不能直接放键值对,这就导致解析器无法识别结构,报错缺少逗号。
另外原JSON还有两个不合理的地方:
plan字段被设计成数组,把plan_type和contract_duration_months拆成两个独立对象,这既不符合“计划属性”的语义,也会增加解析难度;- 如果把
plans改成对象,重复的"full_plan"键会被解析器忽略后面的,因为JSON对象的键必须唯一。
基于语义合理性,我给你两种修复后的JSON方案:
方案1:简洁结构(推荐)
去掉冗余的full_plan层级,直接把每个计划作为数组元素:
{ "id": "100", "plans": [ { "plan_type": "Legacy", "contract_duration_months": "12", "add_ons": { "parking": "yes", "washerDryer": "no" } }, { "plan_type": "New", "contract_duration_months": "0" } ] }
方案2:保留full_plan层级
如果必须保留原有的层级结构,调整为数组包裹full_plan对象:
{ "id": "100", "plans": [ { "full_plan": { "plan": { "plan_type": "Legacy", "contract_duration_months": "12" }, "add_ons": { "parking": "yes", "washerDryer": "no" } } }, { "full_plan": { "plan": { "plan_type": "New", "contract_duration_months": "0" } } } ] }
二、验证并修正Swift结构体
原结构体存在几个和JSON结构不匹配的问题,比如plan字段的数组与对象解析冲突、add_ons的数组与对象不匹配、键映射错误等,我针对上面两种JSON方案分别给出适配的结构体:
适配方案1的结构体
这个结构更简洁,符合Swift的编码规范:
struct TopPlan: Decodable { let id: String let plans: [Plan] } struct Plan: Decodable { let planType: String let contractDurationMonths: String let addOns: AddOns? // 设为可选类型,自动适配缺失add_ons的情况 enum CodingKeys: String, CodingKey { case planType = "plan_type" case contractDurationMonths = "contract_duration_months" case addOns = "add_ons" } } struct AddOns: Decodable { let parking: String let washerDryer: String }
适配方案2的结构体
如果要保留full_plan层级,需要增加一个包装结构体:
struct TopPlan: Decodable { let id: String let plans: [FullPlanWrapper] } struct FullPlanWrapper: Decodable { let fullPlan: FullPlan enum CodingKeys: String, CodingKey { case fullPlan = "full_plan" } } struct FullPlan: Decodable { let plan: PlanDetails let addOns: AddOns? // 可选类型处理字段缺失 enum CodingKeys: String, CodingKey { case plan case addOns = "add_ons" } } struct PlanDetails: Decodable { let planType: String let contractDurationMonths: String enum CodingKeys: String, CodingKey { case planType = "plan_type" case contractDurationMonths = "contract_duration_months" } } struct AddOns: Decodable { let parking: String let washerDryer: String }
关键注意点
- 对于缺失
add_ons的情况,只需把对应的属性设为可选类型(比如AddOns?),Swift的Decodable协议会自动处理,不会抛出解析错误; - 原JSON的
plan数组设计不合理,建议改成单个对象,既符合语义又简化解析; - Swift命名建议用小驼峰(比如
planType对应JSON的plan_type),提升代码可读性。
内容的提问来源于stack exchange,提问作者vrao
相关产品推荐
相关产品推荐

