WCSession didReceiveMessage收消息但方法未执行问题求助
看起来你的核心矛盾是:Watch端明明收到了iOS端的回复,但iOS端的didReceiveMessage方法完全没有执行(既没有打印test1,断点也没触发),同时启动方式也存在异常。我来一步步帮你排查:
1. 最可能的原因:iOS端WCSession代理未正确初始化与激活
从你提供的ParentViewController代码来看,你只声明了var session: WCSession?,但没有完成WCSession的初始化、代理绑定和激活操作。这就导致系统无法把消息传递给这个控制器的didReceiveMessage方法,你看到的回复很可能来自App里其他地方的WCSession代理(比如AppDelegate),或者是缓存的旧回复。
修复步骤:
在ParentViewController的生命周期方法(比如viewDidLoad)里添加WCSession的初始化代码:
override func viewDidLoad() { super.viewDidLoad() // 初始化并激活WCSession if WCSession.isSupported() { session = WCSession.default session?.delegate = self session?.activate() } }
另外,iOS 13及以上版本要求必须实现两个额外的WCSessionDelegate方法,否则会报错,补充上:
// 必须实现的iOS 13+代理方法 func sessionDidBecomeInactive(_ session: WCSession) {} func sessionDidDeactivate(_ session: WCSession) { // 重新激活会话,处理用户切换等场景 session.activate() }
2. 检查WCSession代理的唯一性
如果你的App里还有其他地方(比如AppDelegate)设置了WCSession的代理,那么消息会被那个对象接收处理,而不是ParentViewController。请检查整个项目中所有设置WCSession.default.delegate = xxx的代码,确保只有你期望的控制器(这里是ParentViewController)在处理消息。
3. 修复启动与会话配对问题
你提到启动WatchKit App时iPhone模拟器的App黑屏,单独启动iPhone App后手动启动Watch App无输出,这说明会话可能根本没建立成功:
- 先确保Xcode中iPhone和Watch模拟器是配对状态:打开
Window > Devices and Simulators,选中你的Watch模拟器,检查右侧的“Paired with”是否是目标iPhone模拟器。 - 启动时,选择
WatchKit Appscheme,确保两个模拟器同时启动;或者先单独启动iPhone App(确认它正常运行并激活了WCSession),再启动Watch App,这样会话才能正确建立。
4. 完善Watch端的WCSession初始化
你的Watch端代码只检查了WCSession.isSupported(),但没有初始化和激活session,这可能导致消息发送不稳定。在Watch的InterfaceController中补充:
var session: WCSession? override func awake(withContext context: Any?) { super.awake(withContext: context) if WCSession.isSupported() { session = WCSession.default session?.activate() } }
验证步骤
- 确保上述代码都添加完成,清理项目(
Cmd+Shift+K)后重新编译。 - 先启动iPhone App,确认控制台没有WCSession相关错误。
- 启动Watch App,点击按钮发送消息,此时iOS端的
print("test1")应该会输出,断点也会触发。
内容的提问来源于stack exchange,提问作者owen gerig

