如何在WatchKit中检测iPhone与Apple Watch的连接断开?
在WatchKit端检测Apple Watch与iPhone的连接状态
嗨,我之前也踩过这个坑!在WatchKit端直接用WCSession.default.isReachable判断连接状态确实经常不生效,原因是Watch端的WCSession需要正确激活并通过代理方法监听动态状态变化,而不是只做一次即时判断。下面是我亲测有效的解决方案:
1. 正确初始化并激活WCSession(在Extension Delegate中)
首先要在WatchKit Extension的ExtensionDelegate里完成WCSession的配置,确保设置代理并激活:
import WatchConnectivity class ExtensionDelegate: NSObject, WKExtensionDelegate, WCSessionDelegate { func applicationDidFinishLaunching() { // 先判断设备是否支持WCSession guard WCSession.isSupported() else { print("WCSession is not supported on this device") return } let session = WCSession.default session.delegate = self session.activate() } // 会话激活完成时的回调,可在这里检查初始可达状态 func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { if let error = error { print("Session activation failed: \(error.localizedDescription)") return } if activationState == .activated { print("Session activated successfully. Current reachability: \(session.isReachable)") } } // 关键:监听可达状态变化的核心代理方法 func sessionReachabilityDidChange(_ session: WCSession) { if session.isReachable { // iPhone现在可连接,执行你的同步/播放逻辑 print("Connected to iPhone - ready to sync data and play audio") // 比如调用你的同步方法:syncInfoAndPlayAudio() } else { // 与iPhone断开连接,处理断开后的逻辑 print("Disconnected from iPhone - pause audio or show offline prompt") } } // watchOS要求必须实现的两个代理方法(即使是空实现) func sessionDidBecomeInactive(_ session: WCSession) {} func sessionDidDeactivate(_ session: WCSession) {} }
2. 在Interface Controller中监听状态变化(可选但常用)
如果你的业务逻辑是在Watch的界面控制器(Interface Controller)里执行的,可以通过通知中心把状态变化传递过去:
在ExtensionDelegate的sessionReachabilityDidChange中发送通知:
func sessionReachabilityDidChange(_ session: WCSession) { NotificationCenter.default.post( name: NSNotification.Name(rawValue: "WCSessionReachabilityUpdated"), object: session.isReachable ) }
在Interface Controller中监听通知:
import WatchKit import Foundation class InterfaceController: WKInterfaceController { override func awake(withContext context: Any?) { super.awake(withContext: context) // 注册通知监听 NotificationCenter.default.addObserver( self, selector: #selector(handleReachabilityChange(_:)), name: NSNotification.Name(rawValue: "WCSessionReachabilityUpdated"), object: nil ) } @objc private func handleReachabilityChange(_ notification: Notification) { guard let isReachable = notification.object as? Bool else { return } if isReachable { // 在这里执行你的信息同步和音频播放逻辑 syncRequiredInfo() playTargetAudio() } else { // 断开连接时的处理,比如暂停音频、显示提示 pauseAudio() presentAlert(withTitle: "提示", message: "已与iPhone断开连接", preferredStyle: .alert, actions: [WKAlertAction(title: "确定", style: .default)]) } } // 你的业务方法示例 private func syncRequiredInfo() { // 同步信息的逻辑 } private func playTargetAudio() { // 播放音频的逻辑 } private func pauseAudio() { // 暂停音频的逻辑 } override func willDisappear() { super.willDisappear() // 记得移除通知监听,避免内存泄漏 NotificationCenter.default.removeObserver(self) } }
为什么直接用isReachable不生效?
Watch端的WCSession需要先完成激活流程,而且isReachable是一个动态变化的属性——只有当WCSession处于激活状态,且iPhone处于可达状态时才会返回true。如果只在某个时刻(比如界面初始化时)判断一次,很可能会错过状态变化,必须通过sessionReachabilityDidChange代理方法来实时监听状态的切换。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

