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

将Codable结构体存入UserDefaults后读取返回nil值的问题

解决自定义Codable对象存入UserDefaults后读取返回nil的问题

你遇到的读取时返回nil的问题,根源出在UserModel自定义的解码初始化方法里,我来帮你拆解问题并给出修复方案:

问题核心

在init(from decoder:)方法中,你解析userDetails的方式错误了:

// 错误写法
userDetails = try UserDetail(from: decoder)

你已经通过decoder.container(keyedBy:)获取了对应CodingKeys的容器,但却没有从这个容器里读取userDetails字段,反而直接把整个解码器传给UserDetail的初始化方法。这会让解码器尝试直接解码整个UserDetail结构,而非从userDetails这个键对应的字段中解析数据,最终导致解码失败,返回nil。

修复后的UserModel代码

把解码userDetails的代码改成从容器中读取对应键的值:

struct UserModel : Codable {
    var userDetails : UserDetail?
    var status : Bool?
    var message : String?
    enum CodingKeys: String, CodingKey {
        case userDetails = "userDetails"
        case status = "status"
        case message = "message"
    }
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        // 修正:从容器中解码userDetails字段
        userDetails = try values.decodeIfPresent(UserDetail.self, forKey: .userDetails)
        status = try values.decodeIfPresent(Bool.self, forKey: .status)
        message = try values.decodeIfPresent(String.self, forKey: .message)
    }
}

简化代码的建议

其实你的CodingKeys和结构体属性名完全一致,完全不需要手动定义CodingKeys和init(from decoder:)方法——Codable协议会自动生成默认的编码/解码逻辑,这样能避免手动编码带来的错误。简化后的代码更简洁:

struct UserModel : Codable {
    var userDetails : UserDetail?
    var status : Bool?
    var message : String?
}

只要UserDetail也正确遵循Codable协议,这个版本的代码就能正常完成编码和解码工作。

额外小提示

在iOS 10及以后的版本中,UserDefaults.synchronize()已经被废弃,系统会自动处理数据同步,所以你保存数据的代码里可以去掉defaults.synchronize()这一行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:12:51