如何在iOS端关闭会话时终止Watch上的HKWorkoutSession?
实现iOS端关闭会话时终止Watch端HKWorkoutSession的方案
1. 基于Watch Connectivity实现跨设备指令传递
首先确保iOS主应用和Watch扩展都配置并激活Watch Connectivity会话:
- 两端都导入
WatchConnectivity框架,遵循WCSessionDelegate协议 - 启动会话(两端代码一致):
if WCSession.isSupported() { let session = WCSession.default session.delegate = self session.activate() }
当iOS端用户关闭运动会话时,向Watch端发送终止指令:
// iOS端触发会话关闭时调用 if WCSession.default.isReachable { WCSession.default.sendMessage(["command": "endWorkout"], replyHandler: nil, errorHandler: { error in print("发送终止指令失败:\(error.localizedDescription)") }) }
Watch端监听并响应指令:
// Watch端WCSessionDelegate实现 func session(_ session: WCSession, didReceiveMessage message: [String : Any]) { if message["command"] as? String == "endWorkout" { terminateCurrentWorkout() } }
2. 正确终止HKWorkoutSession
HKWorkoutSession虽无discard或cancel方法,但可通过end()方法终止,并补充状态标记:
// Watch端终止会话的核心方法 private func terminateCurrentWorkout() { guard let session = self.currentWorkoutSession, session.state != .ended else { return } // 结束会话 session.end() // 标记会话为用户主动取消(可选,用于区分正常结束和终止) if let workout = session.workout { var updatedMeta = workout.metadata ?? [:] updatedMeta[HKMetadataKeyWorkoutCancelled] = true let updatedWorkout = HKWorkout(workout: workout, metadata: updatedMeta) // 保存更新后的 workout 到健康库(按需执行) let healthStore = HKHealthStore() healthStore.save(updatedWorkout) { success, error in if let error = error { print("保存取消状态失败:\(error.localizedDescription)") } } } // 清理资源 self.currentWorkoutSession = nil // 停止传感器采集、数据更新等相关逻辑 }
3. 边缘情况处理
- 若Watch端离线,iOS端可使用
transferUserInfo发送指令,Watch端下次激活时会接收:
// iOS端离线时传递指令 WCSession.default.transferUserInfo(["command": "endWorkout"])
Watch端通过session(_:didReceiveUserInfo:)方法处理离线指令。
- 提前在Watch端维护会话状态,避免重复执行终止操作。
内容的提问来源于stack exchange,提问作者emrepun
相关产品推荐
相关产品推荐

