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,但您可以解决这个问题。此外,这也没有解决用户完全完成锻炼并且不想开始新锻炼类型的问题。