JSONDecoder().decode在name字段末尾带逗号时解码失败的原因及解决方法
问题根因
name字段取值末尾的逗号属于JSON字符串的合法内容,完全不会导致解码失败,你对问题原因的初步判断有误,实际触发解码返回nil的原因有两个:
- 你提供的JSON字符串本身不符合规范:最后一个对象中重复定义了两次
Km键,分别赋值为null和数值,JSON标准不允许同一对象内出现重复键,JSONDecoder解析到此处时会直接抛出错误。 - 你使用
try?进行解码,所有错误都会被静默吞掉,仅返回nil,导致你无法看到具体的错误提示,误判了问题诱因。
解决方法
- 优先修正JSON数据源:通知后端删除最后一个对象中重复的
Km字段,保留业务需要的有效值即可,从根源解决格式问题。 - 解码时替换
try?为do-catch捕获错误,方便快速定位问题,示例代码如下:
do { let areas = try JSONDecoder().decode([AreaModel].self, from: data) print("解码成功", areas) } catch { print("解码错误: ", error) // 此处会打印具体的错误原因,比如重复键、类型不匹配等 }
- 如果你暂时无法修改后端返回的JSON,也可以先对原始JSON字符串做预处理,用正则匹配删除重复的
Km字段,再转成Data解码。 - 如果业务上不需要name末尾的逗号,你可以手动实现解码逻辑,自动去除name末尾的多余符号,示例如下:
struct AreaModel: Codable { enum CodingKeys: String, CodingKey { case name case km = "Km" case strid = "Strid" } let name: String let km: Double? let strid: String init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) // 解码name后自动去掉末尾的逗号和空白字符 let rawName = try container.decode(String.self, forKey: .name) self.name = rawName.trimmingCharacters(in: .punctuationCharacters.union(.whitespaces)) self.km = try container.decodeIfPresent(Double.self, forKey: .km) self.strid = try container.decode(String.self, forKey: .strid) } }
内容的提问来源于stack exchange,提问作者Karina
相关产品推荐
相关产品推荐

