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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 03:22:07