@Published 状态没有更新,即使我在 init() 中调用它 - SwiftUI

时间:2021-07-31 02:28:20

标签: swiftui

好像还是不太明白,有没有大神可以解释一下,不光是告诉我哪里不对。所以我已经声明了我的@Published,我创建了一个 init,所以每次调用它时它都会从数据库中获取数据,为什么它没有在视图上刷新?

我退出模拟器并重新午餐后才刷新数据。代码如下:

Adobeservice : RUNNING
AppHostSvc : RUNNING

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

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)")
                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

可能发生的情况是,当您启动应用程序时,“DataStorePersistanceHandler”是 在“init()”中创建并调用“getWallets()”。由于您不会在其他任何地方调用“getWallets()”, 这就是你得到的所有数据,只是第一个数据库查询。 “getWallets()”不会被魔法再次调用 当您使用“DataStorePersistanceHandler”时。你必须自己手动更新 “@Published var userWallets”。这就是为什么当您再次启动应用程序时会获得“新”数据的原因。

在您的代码中的某处,您说您向数据库添加了一个新值,此时您必须 调用“getWallets()”来更新“@Published var userWallets”。不要再做“init()”了。然后您的视图应该刷新。

答案 1 :(得分:0)

假设 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。