HealthKit - 在 HKWorkoutSession 期间更改 HKWorkoutConfiguration?
Posted
技术标签:
【中文标题】HealthKit - 在 HKWorkoutSession 期间更改 HKWorkoutConfiguration?【英文标题】:HealthKit - Change HKWorkoutConfiguration during HKWorkoutSession? 【发布时间】:2021-04-07 05:34:48 【问题描述】:我的问题如下:
我可以在使用期间更改
HKWorkoutConfiguration.activityType
HKWorkoutSession
或者每个HKWorkoutSession
都必须有自己的HKWorkoutConfiguration.activityType
?
我想创建一个锻炼应用程序,您可以在其中创建由具有不同活动类型的不同集合组成的锻炼。例如Shadowing Boxing Workout,包括3组拳击和3组跆拳道(拳击和跆拳道是不同的活动)。
理想情况下,我会在开始时启动一次HKWorkoutSession
,并在完成每个活动的所有集合后结束它,并在中间更改HKWorkoutConfiguration.activityType
。
我目前的做法是基于苹果提供的样本:https://developer.apple.com/documentation/healthkit/workouts_and_activity_rings/speedysloth_creating_a_workout
我将startWorkout()
方法调整为startWorkout(for type: String)
。现在看起来像这样:
// Start the workout.
func startWorkout(for type: String)
// Start the timer.
setUpTimer()
self.running = true
// Create the session and obtain the workout builder.
/// - Tag: CreateWorkout
do
session = try HKWorkoutSession(healthStore: healthStore, configuration: self.workoutConfiguration(for: type))
builder = session.associatedWorkoutBuilder()
catch
// Handle any exceptions.
return
// Setup session and builder.
session.delegate = self
builder.delegate = self
// Set the workout builder's data source.
/// - Tag: SetDataSource
builder.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore,
workoutConfiguration: workoutConfiguration(for: type))
// Start the workout session and begin data collection.
/// - Tag: StartSession
session.startActivity(with: Date())
builder.beginCollection(withStart: Date()) (success, error) in
// The workout has started.
print("New Workout has started")
在方法中,我通过workoutConfiguration(for: type)
获取相应的活动,它从字符串中查找正确的活动。
完成一组训练(例如拳击组)后,我结束训练并开始新的锻炼和训练,并针对新的活动进行新训练。
我对当前方法的问题是我需要在开始新方法之前结束当前的HKWorkoutSession
。但是以示例中的方式结束会话并不会立即执行,因此新的训练集开始时不会使用正确的活动将旧集保存到 HKStore。
因此,我认为只开始一次会话并在其间切换 activityTypes 会很好。但是,我不知道这是否可能(可能是 HKStore 的并发症)以及它是如何完成的。
或者有没有其他聪明的方法来实现这一点?
我刚刚开始接触 ios 编程。
非常感谢任何帮助!
【问题讨论】:
您无法更改健身课程的配置(因此也无法更改锻炼类型),您一次只能启用一个健身课程。 【参考方案1】:免责声明:这不是一个完整的答案,而是我解决问题的方法。
查看workoutSession(_:didChangeTo:from:date:)
方法。 Documentation Link
当一种类型的锻炼结束时,该方法将收到通知。只要您没有致电session.end()
,锻炼会话应该仍然处于活动状态。在开始新的锻炼之前,使用您的 healthStore
实例保存上一个锻炼会话。
它可能看起来像这样;
func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState, from fromState: HKWorkoutSessionState, date: Date)
if toState == .ended
workoutBuilder.endCollection(withEnd: date) (success, error) in
// collection has ended for one type of workout
self.workoutBuilder.finishWorkout (workout, error) in
// unwrap the optional `workout`
guard let completedWorkout = workout else return
// save workout to health store
healthStore.save(completedWorkout) (success, error) in
if success
// begin a new workout by calling your method to start a new workout with a new configuration here
startWorkout(for type: String)
这可能会导致您的计时器出现问题,因为您再次调用setUpTimer
,但您可以使用它。此外,当用户完全完成锻炼并且不想开始新的锻炼类型时,这也没有解决这一点。
【讨论】:
谢谢,你让我走上了正确的道路。我没有在一组完成后结束每个会话,而是停止计时器并调用 builder.endcollection,重置锻炼,然后使用startworkout(for type: String)
开始新的一组。这样,我所有具有不同活动类型和时间的集合都可以正确记录在 healthstore 中。只有当所有的锻炼都完成后,我才结束了训练。显然,即使旧会话没有结束,也可以使用新的锻炼配置开始新会话。
好消息!我很高兴你能够完成它。以上是关于HealthKit - 在 HKWorkoutSession 期间更改 HKWorkoutConfiguration?的主要内容,如果未能解决你的问题,请参考以下文章