为什么在函数中使用时未反映已发布变量的更新值?

问题描述

我正在尝试按照此 tutorial 将 WatchConnectivity 与 SwiftUI 结合使用。在手表的视图模型中,我能够成功接收从 iPhone 发送的消息并将其设置在类的已发布变量中,但是当我尝试在 ContentView 中使用该值时,我只能看到初始值而不是更新后的值。

viewmodelWatch

import Foundation
import WatchConnectivity

class viewmodelWatch : NSObject,WCSessionDelegate,ObservableObject{
    var session: WCSession
    @Published var sessionId = ""
    
    init(session: WCSession = .default){
        self.session = session
        super.init()
        self.session.delegate = self
        session.activate()
    }
    
    func session(_ session: WCSession,activationDidCompleteWith activationState: WCSessionActivationState,error: Error?) {
        
    }
    
    func session(_ session: WCSession,didReceiveMessage message: [String : Any]) {
            dispatchQueue.main.async {
                if let sessionId = message["sessionId"] {
                    self.sessionId = sessionId as! String
                }
            }
        }
}

内容视图

import SwiftUI

struct ContentView: View {
    @Observedobject var model = viewmodelWatch()
    
    var body: some View {
        Button(action: startAction,label: {
          Text("Test")
        })
      
       
    }
    
    func startAction() {
        print("sessionId",self.model.sessionId)

    }
}

解决方法

@Asperi - 那么您建议如何获取更新的 sessionId 值?

一个解决方案是将动作移动到模型中,因此它使用自己的属性进行操作,并直接在按钮(或按钮动作闭包)中使用该动作,例如

class ViewModelWatch : NSObject,WCSessionDelegate,ObservableObject{

    // ... other code

    func startAction() {                     // << move here
        print("sessionId",self.sessionId)

    }
}

struct ContentView: View {
    @ObservedObject var model = ViewModelWatch()

    var body: some View {
        Button(action: model.startAction,label: {     // << use model
          Text("Test")
        })
    }
}