HealthKit - 在 HKWorkoutSession 期间更改 HKWorkoutConfiguration?
HealthKit - Change HKWorkoutConfiguration during HKWorkoutSession?
我的问题如下:
Can I change the HKWorkoutConfiguration.activityType
during a
HKWorkoutSession
or does each HKWorkoutSession
has to have its own
HKWorkoutConfiguration.activityType
?
我想创建一个锻炼应用程序,您可以在其中创建由具有不同 activity 类型的不同组组成的锻炼。例如影子拳击训练,由 3 组拳击和 3 组跆拳道组成(拳击和跆拳道是不同的活动)。
理想情况下,我会在开始时启动一次 HKWorkoutSession
,并在每个 activity 的所有设置完成后结束它,在中间更改 HKWorkoutConfiguration.activityType
。
我目前的做法是基于Apple提供的示例: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)
获得相应的 activity,它从字符串中查找正确的 activity。
一组完成后(例如拳击组),我结束训练并使用新 activity.
开始新的训练和训练。
我当前方法的问题是我需要在开始新方法之前结束当前 HKWorkoutSession
。但是以示例中完成的方式结束会话不会立即执行,因此新的锻炼集开始时没有使用正确的 activity.
将旧集保存到 HKStore
因此我认为只启动一次会话并在其间切换 activityTypes 会很好。但是,我不知道这是否可能(可能是 HKStore 的并发症)以及它是如何完成的。
或者有没有其他聪明的方法来实现这一点?
我刚开始学习 iOS 编程。
非常感谢任何帮助!
免责声明:这不是完整的答案,而是我用来解决问题的方法。
查看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
,但您可以解决这个问题。此外,这也没有解决用户完全完成锻炼并且不想开始新锻炼类型的问题。
我的问题如下:
Can I change the
HKWorkoutConfiguration.activityType
during aHKWorkoutSession
or does eachHKWorkoutSession
has to have its ownHKWorkoutConfiguration.activityType
?
我想创建一个锻炼应用程序,您可以在其中创建由具有不同 activity 类型的不同组组成的锻炼。例如影子拳击训练,由 3 组拳击和 3 组跆拳道组成(拳击和跆拳道是不同的活动)。
理想情况下,我会在开始时启动一次 HKWorkoutSession
,并在每个 activity 的所有设置完成后结束它,在中间更改 HKWorkoutConfiguration.activityType
。
我目前的做法是基于Apple提供的示例: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)
获得相应的 activity,它从字符串中查找正确的 activity。
一组完成后(例如拳击组),我结束训练并使用新 activity.
开始新的训练和训练。我当前方法的问题是我需要在开始新方法之前结束当前 HKWorkoutSession
。但是以示例中完成的方式结束会话不会立即执行,因此新的锻炼集开始时没有使用正确的 activity.
因此我认为只启动一次会话并在其间切换 activityTypes 会很好。但是,我不知道这是否可能(可能是 HKStore 的并发症)以及它是如何完成的。
或者有没有其他聪明的方法来实现这一点?
我刚开始学习 iOS 编程。
非常感谢任何帮助!
免责声明:这不是完整的答案,而是我用来解决问题的方法。
查看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
,但您可以解决这个问题。此外,这也没有解决用户完全完成锻炼并且不想开始新锻炼类型的问题。