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

SwiftUI中从其他View更新数据后HomeView员工列表不更新问题

问题解决:更新员工后列表不刷新的修复方案

核心问题原因

你的EmployeesViewModel中,updateEmployee方法在API更新成功的分支(.success)里没有更新@Published var employees: [User]数组,导致HomeView的List无法感知到数据变化,所以不会刷新UI。

修复步骤

1. 完善ViewModel的updateEmployee方法

在.success分支中,找到数组中对应ID的员工,替换为更新后的对象:

func updateEmployee(employee: User){
    employeesRepository.updateEmployee(employee: employee) {[weak self] result in
        DispatchQueue.main.async {
            guard let self = self else { return }
            switch result {
            case .success(let success):
                // 找到对应ID的员工索引,替换为更新后的对象
                if let index = self.employees.firstIndex(where: { $0.id == success.data.id }) {
                    self.employees[index] = success.data
                }
                // 若想确保数据完全同步,也可以调用getEmployees()重新拉取全量数据
                // self.getEmployees()
                
            case .failure(let error):
                print(String(describing: error))
                switch error{
                case .decodingError(_):
                    self.messageError = "Error generando la decodificacion de la data \(error.localizedDescription)"
                case .encodingError:
                    self.messageError = "Error generando la codificacion de la data \(error.localizedDescription)"
                case .noData:
                    self.messageError = "Error con la data \(error.localizedDescription)"
                case .serverError(let statusCode):
                    self.messageError = "Error del servidor \(statusCode), \(error.localizedDescription)"
                case .transportError(_):
                    self.messageError = "Error del transporte de la peticion \(error.localizedDescription)"
                case .unknownedError(_):
                    self.messageError = "Error desconocido \(error.localizedDescription)"
                case .urlError:
                    self.messageError = "Error con la creación de la url \(error.localizedDescription)"
                }
                self.alertError = true
            }
        }
    }
}

2. 修复Model层的编码解码错误

  • User结构体的枚举名是Codingkeys(小写k),不符合Swift命名规范且会导致编码失败,改为CodingKeys(大写K):
struct User: Decodable, Encodable{
    let id: Int
    var name: String?
    var email: String?
    var sex: String?

    enum CodingKeys: String, CodingKey {
        case id
        case name
        case email
        case sex = "gender"
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.id = try container.decode(Int.self, forKey: .id)
        self.name = try container.decode(String.self, forKey: .name)
        self.email = try container.decode(String.self, forKey: .email)
        self.sex = try container.decode(String.self, forKey: .sex)
    }
}
  • Employees结构体的属性名users与业务(员工)不符,改为employees提升可读性:
struct Employees: Decodable{
    let employees: [User]
    
    enum CodingKeys: String, CodingKey {
        case data
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.employees = try container.decode([User].self, forKey: .data)
    }
}

同时同步修改ViewModel中getEmployees方法的赋值逻辑:self.employees = result.employees。

3. 修复Repository层的数据源初始化问题

EmployeeRepository中缺少employeesDatasource的初始化,补充如下:

final class EmployeeRepository{
    private let employeesDatasource = EmployeeDatasource()
    
    func updateEmployee(employee: User, completionBlock: @escaping (Result<Employee, NetworkError>) -> Void){
        employeesDatasource.updateEmployee(employee: employee, completionBlock: completionBlock)
    }
}

额外优化建议

  • 使用EnvironmentObject传递ViewModel:在HomeView中通过.environmentObject(employeesViewModel)传递ViewModel,子视图用@EnvironmentObject var employeesViewModel: EmployeesViewModel接收,避免手动传递,代码更简洁。
  • 优化User结构体属性:给可选属性设置默认值(如var name: String = ""),减少频繁处理??的冗余代码。
  • 统一错误处理逻辑:把错误信息生成逻辑封装到NetworkError的扩展中,减少ViewModel中的重复代码。
  • 补充编码逻辑:给User结构体添加encode(to:)方法,确保编码时字段名与API要求一致:
func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(id, forKey: .id)
    try container.encode(name, forKey: .name)
    try container.encode(email, forKey: .email)
    try container.encode(sex, forKey: .sex)
}
  • 避免强制解包:用guard let self = self else { return }提前解包,替换self!.alertError = true这类存在崩溃风险的代码。

内容的提问来源于stack exchange,提问作者Robinson Gonzalez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:21:42