向 Apple Watch 发送消息时应用程序崩溃

App crashes when sending message to Apple Watch

我在 iOS 应用程序中有一个 UIButton 操作 (sendMessageToWatch),在 Apple Watch 中有一个标签 (messageLabel)。我想要做的是能够点击 iPhone 中的按钮并在 Apple Watch 的标签中看到它。

出于某种原因,当我点击按钮时,应用程序崩溃但没有输出任何错误。

我错过了什么?

这是代码。

iOS ViewController

import UIKit
import WatchConnectivity

class ViewController: UIViewController, WCSessionDelegate {
    
    var session: WCSession!

    override func viewDidLoad() {
        super.viewDidLoad()
        if WCSession.isSupported() {
            let session = WCSession.default()
            session.delegate = self
            session.activate()
        }
    }
    
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {}
    func sessionDidDeactivate(_ session: WCSession) { }
    func sessionDidBecomeInactive(_ session: WCSession) { }
    
    @IBAction func sendMessageToWatch(_ sender: Any) {
        //Send Message to Watch
        let messageToSend:Dictionary = ["messageFromPhone":"Hello Watch."]
        
        session.sendMessage(messageToSend, replyHandler: { replyMessage in
            // some replay
        }, errorHandler: {error in
            // catch any errors here
        })
    }

}

观看界面控制器

import WatchKit
import Foundation
import WatchConnectivity

class InterfaceController: WKInterfaceController, WCSessionDelegate {
    
    var session: WCSession!
    @IBOutlet var messageLabel: WKInterfaceLabel!

    func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
        //handle received message
        let value = message["messageFromPhone"] as? String
        DispatchQueue.main.async {
            self.messageLabel.setText(value)
        }
    }
    
    override func awake(withContext context: Any?) {
        super.awake(withContext: context)
    }

    override func willActivate() {
        // This method is called when watch view controller is about to be visible to user
        super.willActivate()
        
        if (WCSession.isSupported()) {
            session = WCSession.default()
            session.delegate = self
            session.activate()
        }
    }

    override func didDeactivate() {
        // This method is called when watch view controller is no longer visible
        super.didDeactivate()
    }
    
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {}
}

您正在 viewDidLoad 中声明另一个会话对象,并用 let 重新声明它。只需删除它:

var session: WCSession!
override func viewDidLoad() {
    super.viewDidLoad()
    if WCSession.isSupported() {
        session = WCSession.default()
        session.delegate = self
        session.activate()
    }
}