You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WatchKit Extension代理方法未实现问题求助

WatchConnectivity Error: Delegate Method Not Implemented & Session Not Activated Issues

我正在通过一个简单应用学习WatchKit Connectivity,已经花了两天时间排查以下错误,但毫无进展:{app name}_WatchKit_Extension.InterfaceController does not implement delegate method。我完全复制了苹果官方的SimpleWatchConnectivity示例代码,也查了各类论坛,但都没解决。

我的代码能正常构建运行,但在手表端执行iOS ViewController里的这段代码时出现错误:

if (WCSession.isSupported()) {
    WCSession.default.delegate = self;
    WCSession.default.activate()
    if let messageText = textField.text{
        WCSession.default.sendMessage(["message": messageText] ,replyHandler: {replyMessage in
            print(replyMessage)
        } , errorHandler: {error in
            print( error.localizedDescription)}
        )
    }
}

报错信息

手表端(仅发送第二条消息时出现,第一条无报错):

2018-01-06 10:39:20.522995+1100 messageDemo WatchKit Extension[338:743006] [WC] -[WCSession onqueue_handleDictionaryMessageRequest:withPairingID:]_block_invoke delegate messageDemo_WatchKit_Extension.InterfaceController does not implement delegate method
2018-01-06 10:39:20.524378+1100 messageDemo WatchKit Extension[338:743006] [WC] -[WCSession _onqueue_sendResponseError:identifier:dictionaryMessage:] identifier: A150D814-453C-44B7-B970-913697526D6A with WCErrorCodeDeliveryFailed

手机端调试时的报错:

2018-01-07 09:47:23.319221+1100 messageDemo[6628:1549809] [WC] -[WCSession _onqueue_notifyOfMessageError:messageID:withErrorHandler:] (null) errorHandler: YES with WCErrorCodeSessionNotActivated
2018-01-07 09:47:23.321103+1100 messageDemo[6628:1549978] [WC] -[WCSession _onqueue_notifyOfMessageError:messageID:withErrorHandler:]_block_invoke dropping as pairingIDs no longer match. pairingID (null), client pairingID: (null)
WatchConnectivity session has not been activated.

我的InterfaceController代码:

import WatchKit
import Foundation
import WatchConnectivity

class InterfaceController: WKInterfaceController , WCSessionDelegate {
    func session(_ session: WCSession , activationDidCompleteWith activationState: WCSessionActivationState , error: Error?) {
        print("activationDidCompleteWith:\(activationState )")
    }
    func sessionReachabilityDidChange(_ session: WCSession) {
        // print("sessionReachabilityDidChange")
    }
    @IBOutlet var messageLabel: WKInterfaceLabel!
    override func awake(withContext context: Any?) {
        super.awake(withContext: context)
    }
    override func willActivate() {
        super.willActivate()
        if (WCSession.isSupported()) {
            WCSession.default.delegate = self;
            WCSession.default.activate()
        }
    }
    override func didDeactivate() {
        super.didDeactivate()
    }
    private func session(session: WCSession, didReceiveMessage message: [String : Any] , replyHandler: @escaping ([String : Any]) -> Void) {
        self.messageLabel.setText(message["message"]! as? String)
    }
    func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
        self.messageLabel.setText(message["message"]! as? String)
    }
    func session(_ session: WCSession, didReceiveMessageData messageData: Data) {
        print("HERE01")
    }
    func session(_ session: WCSession, didReceiveMessageData messageData: Data, replyHandler: @escaping (Data) -> Void) {
        self.session(session, didReceiveMessageData: messageData)
        print("HERE02")
    }
    func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
        print("HERE03")
    }
    func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) {
        print("HERE04")
    }
    func session(_ session: WCSession, didFinish userInfoTransfer: WCSessionUserInfoTransfer, error: Error?) {
        print("HERE05")
    }
    func session(_ session: WCSession, didReceive file: WCSessionFile) {
        print("HERE06")
    }
    func session(_ session: WCSession, didFinish fileTransfer: WCSessionFileTransfer, error: Error?) {
        print("HERE07")
    }
}

我加了多个打印语句覆盖所有场景,但还是出现上述错误。恳请各位提供技术帮助。


问题分析与解决方案

兄弟,我一眼就看到你代码里的两个关键问题,这就是导致报错的根源:

1. Delegate方法签名错误(手表端报错的核心原因)

你写的带replyHandler的didReceiveMessage方法是旧的Objective-C风格签名,还加了private修饰符,WatchConnectivity框架根本识别不到这个方法!

正确的Swift 3+方法签名应该是这样的:

func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void) {
    self.messageLabel.setText(message["message"] as? String)
    // 必须调用replyHandler!否则手机端会一直等待响应,最终触发超时错误
    replyHandler(["status": "message received successfully"])
}

你原来的方法少了参数前的_,而且private修饰符会让系统无法识别这个delegate方法,一定要去掉。

2. 手机端Session激活时机错误(导致WCErrorCodeSessionNotActivated)

你在手机端代码里调用activate()后立刻发送消息,但activate()是异步操作!Session还没完成激活流程就发消息,自然会报错。

正确的做法是:在手机端的WCSessionDelegate里实现activationDidCompleteWith方法,等激活完成后再发送消息。给你个手机端ViewController的示例:

import UIKit
import WatchConnectivity

class ViewController: UIViewController, WCSessionDelegate {
    @IBOutlet weak var textField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        if WCSession.isSupported() {
            WCSession.default.delegate = self
            WCSession.default.activate()
        }
    }
    
    // 实现这个方法,确认Session激活完成
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        if let error = error {
            print("Session激活失败: \(error.localizedDescription)")
            return
        }
        print("Session激活成功: \(activationState)")
    }
    
    // 假设你有一个发送按钮的点击事件
    @IBAction func sendMessageTapped(_ sender: UIButton) {
        guard let messageText = textField.text, !messageText.isEmpty else { return }
        // 发送前先检查Session是否激活且可达
        guard WCSession.default.isActivated, WCSession.default.isReachable else {
            print("Session未激活或不可达")
            return
        }
        WCSession.default.sendMessage(["message": messageText], replyHandler: { reply in
            print("收到回复: \(reply)")
        }, errorHandler: { error in
            print("发送失败: \(error.localizedDescription)")
        })
    }
    
    // iOS端必须实现这两个必填的delegate方法
    func sessionDidBecomeInactive(_ session: WCSession) {}
    func sessionDidDeactivate(_ session: WCSession) {
        session.activate() // 重新激活,处理切换配对等场景
    }
}

3. 额外优化建议

  • 手表端的willActivate每次界面激活都会调用,重复设置delegate和activate()虽然不会崩溃,但建议移到awake(withContext:)里,只初始化一次。
  • 发送消息前一定要检查WCSession.default.isReachable,确保手表和手机处于连接状态。
  • 所有带replyHandler的消息必须调用replyHandler,否则会触发超时错误。

按照上面的修改,你应该就能解决这两个报错了!


内容的提问来源于stack exchange,提问作者BlastWave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:43:19