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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:53:51