了解有关为 ios 打造出色体能训练体验的最佳做法。探究体能训练会话的生命周期,探索 apple watch 上和 iphone 上体能训练的不同之处,并了解如何使用实时活动和 siri 来提升 app 的锁屏体验。
此文章由AI生成,可能存在错误,如有问题,请联系djs66256@163.com
在 iOS 和 iPadOS 上使用 HealthKit 追踪体能训练
HealthKit 作为苹果健康数据管理的核心框架,为开发者提供了追踪体能训练的丰富 API。本文将详细介绍如何在 iOS 和 iPadOS 设备上实现完整的训练追踪体验。
训练会话基础实现
建立完整的训练会话流程包含几个关键步骤:
会话配置与启动
开发首先需要创建训练配置对象,设置活动类型(如跑步)和位置类型(如户外)。配置完成后,通过 HKWorkoutSession 初始化会话实例,并关联训练构建器与数据源:
let configuration = HKWorkoutConfiguration()
configuration.activityType = .running
configuration.locationType = .outdoor
let session = try HKWorkoutSession(healthStore: healthStore, configuration: configuration)
let builder = session.associatedWorkoutBuilder()
builder.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore,
workoutConfiguration: configuration)
启动前调用 prepare 方法让设备传感器预热,随后显示3秒倒计时,确保训练开始时就能获取准确数据:
session.prepare()
session.startActivity(with: startDate)
try await builder.beginCollection(at: startDate)
数据处理与会话结束
训练构建器委托方法负责处理实时收集的数据:
func workoutBuilder(_ workoutBuilder: HKLiveWorkoutBuilder,
didCollectDataOf collectedTypes: Set<HKSampleType>) {
for type in collectedTypes {
guard let quantityType = type as? HKQuantityType else { return }
let statistics = workoutBuilder.statistics(for: quantityType)
updateForStatistics(statistics)
}
}
结束训练时需要依次调用停止、结束收集和完成训练的方法:
session.stopActivity(with: .now)
try await builder.endCollection(at: change.date)
let finishedWorkout = try await builder.finishWorkout()
session.end()
设备差异性处理
iOS/iPadOS 与 Apple Watch 在训练追踪方面存在几个重要区别:
传感器可用性
iPhone 和 iPad 本身不配备心率传感器,但可以配对支持心率 GAT 配置文件的外设。系统会自动处理这些设备的数据,将其存入健康数据库。
数据类型差异
训练数据分为两类:
- 系统生成类型:如卡路里和距离等基础指标
- 收集类型:应用自定义收集的指标(如饮水量)
开发者可以通过数据源的 enable/disable collection 方法动态调整收集的数据类型。
锁屏状态处理
iOS 设备在训练时可能锁屏,系统会显示特殊权限提示,允许应用在锁屏时继续访问训练数据。这是展示实时活动的理想场景:
- 设备锁定时若无数据访问权限,应仅显示训练时长
- 可以结合实时活动和 Siri 意图提升锁屏体验
增强训练体验
锁屏 Siri 支持
通过实现特定意图处理器,应用可以支持锁屏状态下的语音控制:
public class IntentHandler: INExtension {}
extension IntentHandler: INStartWorkoutIntentHandling
extension IntentHandler: INPauseWorkoutIntentHandling
extension IntentHandler: INResumeWorkoutIntentHandling
extension IntentHandler: INEndWorkoutIntentHandling
处理逻辑需要检查当前训练状态并做出相应响应:
public func handle(intent: INStartWorkoutIntent) async -> INStartWorkoutIntentResponse {
let state = await WorkoutManager.shared.state
switch state {
case .running, .paused, .prepared, .stopped:
return INStartWorkoutIntentResponse(code: .failureOngoingWorkout,
userActivity: nil)
default:
WorkoutManager.shared.setWorkoutConfiguration(activityType: .running,
location: .outdoor)
return INStartWorkoutIntentResponse(code: .success, userActivity: nil)
}
}
崩溃恢复机制
iOS 新增了场景委托来处理训练恢复:
func application(_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions) -> UISceneConfiguration {
if options.shouldHandleActiveWorkoutRecovery {
let store = HKHealthStore()
store.recoverActiveWorkoutSession(completion: { (workoutSession, error) in
Task {
await WorkoutManager.shared.recoverWorkout(recoveredSession: workoutSession)
}
})
}
// 返回场景配置
}
恢复时只需重建数据源即可继续之前的会话:
func recoverWorkout(recoveredSession: HKWorkoutSession) {
session = recoveredSession
builder = recoveredSession.associatedWorkoutBuilder()
let dataSource = HKLiveWorkoutDataSource(healthStore: healthStore,
workoutConfiguration: workoutConfiguration)
builder?.dataSource = dataSource
}
开发最佳实践
- 优先在 Apple Watch 上启动训练以获得完整指标
- 仅请求必要数据类型的健康权限
- 始终使用训练构建器 API 保存训练数据
- 已有 Apple Watch 应用可以轻松扩展到 iOS/iPadOS 平台
- 及时同步训练数据到 iPhone(参考多设备训练专题)
相关资源
开发者可以参考以下资源获取更多信息:
相关视频
了解 HealthKit Medications API
利用 App Intents 为用户奉上 App 的核心功能
了解 ActivityKit
构建多设备训练 App
