@Published state is not getting updated, even though I called it in init() – SwiftUI

Solution for @Published state is not getting updated, even though I called it in init() – SwiftUI
is Given Below:

It seems I still don’t quite understand it, can someone please explain it, not only tell me what’s wrong. So I have declared my @Published, I created an init so every time it’s called it fetches the data from the DB, why is it not refreshing on the View?

The data was only refreshed after I quit the simulator and relunched. Here’s the code:

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

This is how I’m calling it in the view:

@EnvironmentObject var dataStorePersistanceHandler: DataStorePersistanceHandler

...

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

Assuming self.authSessionManager.getUser() call is really synchronous and Amplify.DataStore.query(...) is asynchronous and DataStorePersistanceHandler environment object created and injected correctly, try the following:

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

Note: init is called on the main queue anyway, but API callback might be called on work queue, but published property must be set on main UI queue to make UI updated.

What is probably happening is that when you start your app, “DataStorePersistanceHandler” is
created and calls “getWallets()” in the “init()”. Since you don’t call “getWallets()” anywhere else,
that is all the data you get, just this first db query. “getWallets()” does not get called again by magic
when you use “DataStorePersistanceHandler”. You have to manually do it yourself to update the
“@Published var userWallets”. That is why you get the “new” data when you start the app again.

Somewhere in your code you say you add a new value to the db, at that point you have to
call “getWallets()” to update the “@Published var userWallets”. Not do “init()” again. Your view should then refresh.