Swift中更新UserDefaults的User结构体时如何避免覆盖原有属性
解决用户头像更新时覆盖原有属性的问题
核心问题是你更新头像时新建了空值的User实例,直接覆盖了本地保存的完整用户数据。正确做法是先读取本地已保存的用户信息,再基于原有数据修改头像URL后重新保存。
步骤1:为PersistenceManager添加读取用户的方法
首先需要能从本地获取已保存的User实例,给PersistenceManager新增读取逻辑:
extension PersistenceManager { static func fetchUserProfile(completion: @escaping (Result<User, Error>) -> Void) { // 示例以UserDefaults为例,根据你的实际存储方式调整 guard let data = UserDefaults.standard.data(forKey: "savedUser") else { completion(.failure(NSError(domain: "Persistence", code: -1, userInfo: [NSLocalizedDescriptionKey: "未找到已保存的用户"]))) return } do { let user = try JSONDecoder().decode(User.self, from: data) completion(.success(user)) } catch { completion(.failure(error)) } } }
步骤2:修改头像更新逻辑,复用原有用户数据
更新updateUserProfileImageInFirestore函数,先读取本地用户数据,再仅更新头像字段后保存:
func updateUserProfileImageInFirestore(_ imageUrl: String) { guard let uid = Auth.auth().currentUser?.uid else { print("当前无登录用户") return } let db = Firestore.firestore() db.collection("users").document(uid).updateData(["profileImageUrl": imageUrl]) { [weak self] error in if let error = error { print("更新Firestore数据失败: \(error.localizedDescription)") return } print("头像URL已成功更新到Firestore") // 读取本地已保存的用户数据 PersistenceManager.fetchUserProfile { result in switch result { case .success(let existingUser): // 基于原有用户数据创建新实例,仅替换头像URL let updatedUser = User( uid: existingUser.uid, name: existingUser.name, profileImageUrl: imageUrl, bookmarkedRecipes: existingUser.bookmarkedRecipes ) // 保存更新后的用户数据 PersistenceManager.saveUserProfile(user: updatedUser) { saveError in if let saveError = saveError { print("保存用户数据失败: \(saveError.localizedDescription)") } else { print("本地用户数据已更新") // 同步更新UI上的用户实例 self?.profileVC?.user = updatedUser } } case .failure(let fetchError): print("读取已有用户数据失败: \(fetchError.localizedDescription)") } } } }
可选优化:调整User结构体属性为可变(如果业务允许)
如果你的业务逻辑允许,可以把uid和name改成var类型,这样无需新建实例,直接修改已有对象的头像字段即可:
struct User: Codable { var uid: String? var name: String? var profileImageUrl: String? var bookmarkedRecipes: [String]? }
之后读取到existingUser后,直接修改保存:
var updatedUser = existingUser updatedUser.profileImageUrl = imageUrl PersistenceManager.saveUserProfile(user: updatedUser) { ... }
内容的提问来源于stack exchange,提问作者asduskun
相关产品推荐
相关产品推荐

