WatchOS WCSession无法激活/代理缺失问题求助
WCSession无法激活、watchOS设备不可达的问题修复
问题描述
我尝试在Xcode模拟器中通过Watch Connectivity的WCSession实现iOS应用与watchOS应用的连接,但手表始终显示不可达,会话也无法激活。我使用同一个SyncService类,同时设置iOS和watchOS为目标,并在应用启动的.onAppear方法中初始化它。以下是我的代码:
原SyncService类
import Foundation import WatchConnectivity class SyncService : NSObject, WCSessionDelegate { private var session: WCSession = .default init(session: WCSession = .default) { super.init() self.session = session self.session.delegate = self print("Reachable :",session.isReachable) #if os(iOS) print("Connection provider initialized on phone") #endif #if os(watchOS) print("Connection provider initialized on watch") #endif self.connect() print("Details",self.session) } func connect() { guard WCSession.isSupported() else { print("WCSession is not supported") return } switch self.session.activationState { case .activated: print("WCSession activated successfully") case .inactive: print("Unable to activate the WCSession. Error:") case .notActivated: print("Unexpected .notActivated state received after trying to activate the WCSession") @unknown default: print("Unexpected state received after trying to activate the WCSession") } session.activate() } func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { } #if os(iOS) func sessionDidBecomeInactive(_ session: WCSession) { } func sessionDidDeactivate(_ session: WCSession) { } #endif // func sendMessage(_ key: String, _ message: String, _ errorHandler: ((Error) -> Void)?) { // if session.isReachable { // session.sendMessage([key : message], replyHandler: nil) { (error) in // print(error.localizedDescription) // if let errorHandler = errorHandler { /// errorHandler(error) // } // } // } // } }
原iOS应用入口
import SwiftUI @main struct ConnectivityApp: App { var body: some Scene { WindowGroup { ContentView() .onAppear{ var model = SyncService() } } } }
原watchOS应用入口
import SwiftUI @main struct Connectivity_Watch_AppApp: App { var body: some Scene { WindowGroup { ContentView() .onAppear{ var model = SyncService() } } } }
核心问题与修复步骤
1. SyncService实例生命周期过短
原代码中,SyncService是在.onAppear闭包内创建的局部变量,闭包执行完毕后实例立即被销毁,导致WCSession还未完成激活就被释放,代理方法无法触发,会话也无法维持激活状态。
- 修复:在App结构体中持有
SyncService实例,保证其生命周期与应用一致。
2. 激活状态检查时机错误
connect()方法中,调用session.activate()前就检查activationState,此时会话还未开始激活,状态必然是.notActivated,这个检查没有实际意义。应在activationDidCompleteWith代理方法中处理激活结果。
3. 未处理激活错误与状态
原activationDidCompleteWith方法为空实现,无法得知激活失败的具体原因,也无法确认激活是否成功。需在此方法中检查错误和最终激活状态。
4. 未监听可达性变化
未实现sessionReachabilityDidChange代理方法,无法实时获取设备的可达状态变化。
修改后的代码
SyncService类(单例模式)
import Foundation import WatchConnectivity class SyncService: NSObject, WCSessionDelegate { static let shared = SyncService() // 全局单例,保证实例唯一且生命周期稳定 private let session: WCSession = .default private override init() { super.init() self.session.delegate = self #if os(iOS) print("Connection provider initialized on phone") #endif #if os(watchOS) print("Connection provider initialized on watch") #endif connect() } func connect() { guard WCSession.isSupported() else { print("WCSession is not supported on this device") return } session.activate() } // 处理会话激活结果 func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { if let error = error { print("WCSession activation failed: \(error.localizedDescription)") return } switch activationState { case .activated: print("WCSession activated successfully") print("Initial reachability state: \(session.isReachable)") case .inactive: print("WCSession is inactive") case .notActivated: print("WCSession failed to activate") @unknown default: print("Unexpected WCSession activation state") } } // 监听设备可达性变化 func sessionReachabilityDidChange(_ session: WCSession) { print("Reachability updated: \(session.isReachable)") } #if os(iOS) func sessionDidBecomeInactive(_ session: WCSession) { print("WCSession became inactive") } func sessionDidDeactivate(_ session: WCSession) { print("WCSession deactivated, reactivating...") session.activate() // iOS端会话失效后需重新激活 } #endif }
iOS应用入口
import SwiftUI @main struct ConnectivityApp: App { let syncService = SyncService.shared // 持有实例,保证生命周期 var body: some Scene { WindowGroup { ContentView() } } }
watchOS应用入口
import SwiftUI @main struct Connectivity_Watch_AppApp: App { let syncService = SyncService.shared // 持有实例,保证生命周期 var body: some Scene { WindowGroup { ContentView() } } }
额外注意事项
- 确保iOS和watchOS应用的Bundle ID前缀一致,watchOS应用的Bundle ID需为iOS应用的子ID(例如iOS为
com.yourname.Connectivity,watchOS为com.yourname.Connectivity.watchkitapp)。 - 在Xcode模拟器中,需先启动iOS应用,再通过iOS模拟器的
Hardware > Watch > Show Watch Home Screen启动watch应用,确保两者处于配对状态。 - 若模拟器连接异常,可尝试重启Xcode、模拟器,或重置模拟器的内容与设置。
内容的提问来源于stack exchange,提问作者Ahmed Kazez
相关产品推荐
相关产品推荐

