当从另一个 ObservedObject 链接时,View 不会对 Published 属性 的更改做出反应

View not reacting to changes of Published property when its chained from another ObservedObject

下面是 SwiftUI 视图,它拥有一个 ViewModel,逻辑是如果 viewModel.authenticationService.user 包含一个用户对象,那么它将显示 HomeView,否则将要求登录。所以最初 viewModel.authenticationService.user 是 nil 并且用户登录成功用户对象不再是 nil.

查看

struct WelcomeView: View {
    
    @ObservedObject private var viewModel: WelcomeView.Model
    @State private var signInActive: Bool = false
    
    init(viewModel: WelcomeView.Model) {
        self.viewModel = viewModel
    }
    
    var body: some View {
        if viewModel.authenticationService.user != nil {
            HomeView()
        } else { 
            LoginView()
        }
    } 

ViewModel

extension WelcomeView {
    
    final class Model: ObservableObject {
        
        @ObservedObject var authenticationService: AuthenticationService
        
        init(authenticationService: AuthenticationService) {
            self.authenticationService = authenticationService
        }
    }
}

AuthenticationService

final class AuthenticationService: ObservableObject {
    
    @Published var user: User?
    private var authenticationStateHandle: AuthStateDidChangeListenerHandle?
    
    init() {
        addListeners()
    }
    
    private func addListeners() {
        if let handle = authenticationStateHandle {
            Auth.auth().removeStateDidChangeListener(handle)
        }
        
        authenticationStateHandle = Auth.auth()
            .addStateDidChangeListener { _, user in
                self.user = user
            }
    }
    
    static func signIn(email: String, password: String, completion: @escaping AuthDataResultCallback) {
        if Auth.auth().currentUser != nil {
            Self.signOut()
        }
        Auth.auth().signIn(withEmail: email, password: password, completion: completion)
    }
}

但是,当用某个值更新用户对象时,它不会更新视图。我不确定,因为我是反应式编程方式的新手。有一个 View -> ViewModel -> Service 链,发布的用户 属性 在 Service class 中,一旦用户登录就会成功更新。

我是否需要在 ViewModel 中添加一个侦听器来响应已发布的服务 属性?或者有什么直接的方法可以使这种情况起作用并获得 UI 更新?

如果存在从 View -> ViewModel -> Services 的链的情况:

@ObservedObject 不适用于 类。仅适用于 SwiftUI 视图(结构)。因此,如果您想从服务中观察视图模型的变化,您需要手动 listen/subscribe 它。

self.element.$value.sink(
                receiveValue: { [weak self] _ in
                    self?.objectWillChange.send()
                }
            )

您也可以使用.assign。查找更多详细信息 here