首页 > 解决方案 > @Published 状态没有得到更新,即使我在 init() 中调用它 - SwiftUI

问题描述

看来我还是不太明白,谁能解释一下,不仅告诉我出了什么问题。所以我已经声明了我的@Published,我创建了一个 init,所以每次调用它都会从数据库中获取数据,为什么它不刷新视图?

数据只有在我退出模拟器并重新启动后才会刷新。这是代码:

final class DataStorePersistanceHandler: ObservableObject {
    
    @Published var userWallets: List<Wallet> = List<Wallet>()
    
    let authSessionManager = AuthSessionManager()
    
    init() {
        getWallets()
    }
    
    // MARK: Get local/online user wallets
    func getWallets() {
        DispatchQueue.main.async {
            let user = self.authSessionManager.getUser()
            
            Amplify.DataStore.query(User.self, byId: user.userId) {
                switch $0 {
                case .success(let wallet):
                    if let userWithWallets = wallet {
                        if let wallets = userWithWallets.wallets {
                            self.userWallets = wallets
                        }
                    } else {
                        print("No wallets found for this user")
                    }
                case .failure(let error):
                    print("User not found - \(error.localizedDescription)")
                }
            }
        }
    }
}

这就是我在视图中调用它的方式:

@EnvironmentObject var dataStorePersistanceHandler: DataStorePersistanceHandler

...

if(dataStorePersistanceHandler.userWallets.count == 0) {
    someView()
} else {
    Text("SomeText")
}

标签: swiftui

解决方案


假设self.authSessionManager.getUser()调用确实是同步的并且Amplify.DataStore.query(...)是异步的并且DataStorePersistanceHandler环境对象被正确创建和注入,请尝试以下操作:

func getWallets() {
        let user = self.authSessionManager.getUser()
        
        Amplify.DataStore.query(User.self, byId: user.userId) {
            switch $0 {
            case .success(let wallet):
                if let userWithWallets = wallet {
                    if let wallets = userWithWallets.wallets {
                       DispatchQueue.main.async {               // << here !!
                          self.userWallets = wallets
                       }
                    }
                } else {
                    print("No wallets found for this user")
                }
            case .failure(let error):
                print("User not found - \(error.localizedDescription)")
            }
        }
    }
}

注意:无论如何都会在主队列上调用 init,但可能会在工作队列上调用 API 回调,但必须在主 UI 队列上设置发布属性才能更新 UI。


推荐阅读