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

如何使用UserDefaults保存和获取含嵌套Picture的User模型详情

嵌套模型的UserDefaults保存与读取实现方案

我来帮你搞定这个嵌套模型的存储和读取问题,结合你的场景一步步来:

第一步:让模型支持序列化

UserDefaults只能存储可序列化的类型(比如Data、字符串这些),所以咱们得让User和Picture模型支持序列化。这里推荐用Swift原生的Codable协议,比第三方库更简洁稳定;如果你还想用ObjectMapper,我也会给出对应的方案。

方案1:用Codable协议改造模型

// Picture模型,对应你的user_profile_photo字段
struct Picture: Codable {
    let id: Int
    let userId: Int
    let photoUrl: String
    
    // 映射JSON里的下划线命名到Swift的驼峰命名
    enum CodingKeys: String, CodingKey {
        case id
        case userId = "user_id"
        case photoUrl = "photo_url"
    }
}

// User模型
struct User: Codable {
    let id: Int
    let email: String
    let userProfilePhoto: Picture
    
    enum CodingKeys: String, CodingKey {
        case id
        case email
        case userProfilePhoto = "user_profile_photo"
    }
}

// 你的LoginResponse也要支持Codable,才能正常解析
struct LoginResponse: Codable {
    let user: User
    // 其他登录返回的字段(比如token之类的)也可以加在这里
}

方案2:用ObjectMapper转成JSON字符串

如果你继续用ObjectMapper解析,那可以把模型转成JSON字符串再存储:

// 确保你的User和Picture模型已经实现了Mappable协议
if let userJsonString = loginResponseObj.user?.toJSONString() {
    UserDefaults.standard.set(userJsonString, forKey: "currentUser")
}

第二步:保存User模型到UserDefaults

假设你已经通过Mapper解析得到了loginResponseObj,现在用Codable方案来保存:

do {
    // 把User对象编码成Data
    let userData = try JSONEncoder().encode(loginResponseObj.user)
    // 存到UserDefaults,用一个固定的key比如"currentUser"
    UserDefaults.standard.set(userData, forKey: "currentUser")
    // 可选:调用synchronize确保立即写入(iOS 10+其实可以不用,但加上更稳妥)
    UserDefaults.standard.synchronize()
} catch {
    print("保存用户数据失败:\(error.localizedDescription)")
}

第三步:从UserDefaults读取并还原User模型

需要把存储的Data(或JSON字符串)转回到User对象:

对应Codable方案的读取代码

// 封装成一个方法方便调用
func getCurrentUser() -> User? {
    // 先取出存储的Data
    guard let userData = UserDefaults.standard.data(forKey: "currentUser") else {
        return nil
    }
    // 解码成User对象
    do {
        let user = try JSONDecoder().decode(User.self, from: userData)
        return user
    } catch {
        print("读取用户数据失败:\(error.localizedDescription)")
        return nil
    }
}

// 使用示例
if let currentUser = getCurrentUser() {
    // 访问用户详情
    print("用户ID:\(currentUser.id)")
    print("邮箱:\(currentUser.email)")
    print("头像URL:\(currentUser.userProfilePhoto.photoUrl)")
} else {
    print("没有找到已存储的用户数据")
}

对应ObjectMapper方案的读取代码

func getCurrentUser() -> User? {
    guard let userJsonString = UserDefaults.standard.string(forKey: "currentUser") else {
        return nil
    }
    // 把JSON字符串转成User对象
    return Mapper<User>().map(JSONString: userJsonString)
}

一些额外提醒

  • 如果你的模型里有可选字段(比如用户可能没有头像),记得把对应的属性改成可选类型(比如let userProfilePhoto: Picture?),避免解码失败。
  • UserDefaults是轻量级存储,只适合存这种小数据,别用来存大文件(比如图片本身,像你的JSON那样存URL就够了)。
  • 可以把这些存储读取的逻辑封装成一个工具类,比如UserDefaultsManager,这样代码更整洁,也方便复用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:03:27