Swift4中使用Codable协议解析JSON后字段为空的问题求助
问题原因与解决方案
你的问题出在结构体属性的默认值定义上,导致JSONDecoder无法正确将JSON中的值赋值给对象字段,具体分析和修复如下:
核心问题
你给结构体的所有let类型属性都设置了默认值(比如let authToken: String? = ""),这会带来两个关键问题:
let是不可变属性,一旦用默认值初始化后,JSONDecoder无法修改它的值;- 手动给可选类型赋值
""违背了可选类型的设计初衷——可选类型默认就是nil,不需要额外赋空字符串。
这就是为什么你能生成对象实例,但所有字段都保留了默认值,完全没有被返回的JSON数据覆盖。
修复方案
方案1:移除默认值(推荐)
如果你的属性不需要默认值,直接定义为可选的let属性即可,JSONDecoder会通过合成的Codable初始化器自动用JSON中的值初始化它们:
struct LoginCodableEntity: Codable { let authToken: String? let status: String? let errorMessage: String? let errorCode: Int? private enum CodingKeys: String, CodingKey { case status case errorMessage = "message" case authToken = "auth_token" case errorCode = "code" } }
方案2:保留默认值(改为var)
如果你确实需要默认值兜底,需要把属性改为var(可变属性),这样JSONDecoder才能在初始化后用JSON值覆盖默认值:
struct LoginCodableEntity: Codable { var authToken: String? = "" var status: String? = "" var errorMessage: String? = "" var errorCode: Int? private enum CodingKeys: String, CodingKey { case status case errorMessage = "message" case authToken = "auth_token" case errorCode = "code" } }
验证效果
修改后,解码你提供的错误返回JSON:
{ code = 910; message = "Credentials denied"; status = error; }
你会得到正确的对象实例:
LoginCodableEntity(authToken: nil, status: Optional("error"), errorMessage: Optional("Credentials denied"), errorCode: Optional(910))
(注:authToken为nil是因为该错误返回中没有auth_token字段,符合可选类型的预期)
内容的提问来源于stack exchange,提问作者AlexBerd
相关产品推荐
相关产品推荐

