如何使用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
相关产品推荐
相关产品推荐

