Search code examples
swiftwatchkitappdelegatehealthkitpause

HKWorkoutSessionDelegate : workoutSession(_:didGenerate:) problem with pause detection


I am building a running workout for Apple Watch and I have a problem to implement an "auto-pause" feature. The HKWorkoutSessionDelegate : workoutSession(_:didGenerate:) delegate is supposed to get some pause events generated by the system.

The problem I encounter is that my session never starts: the pause event is immediately sent to the delegate.

My code:

func workoutSession(_ workoutSession: HKWorkoutSession, didGenerate event: HKWorkoutEvent) {
            // press 2 buttons
            if(event.type == HKWorkoutEventType.pauseOrResumeRequest) {
                print("Detected Press")
                if workoutData.isPaused == false {
                    pauseWorkout()
                }
                else {
                    resumeWorkout()
                }
            }

            // Auto-pause
            if event.type == HKWorkoutEventType.motionPaused && workoutSettings.autoPause {
                print("Auto Pause")
                pauseWorkout()
            }
            if event.type == HKWorkoutEventType.motionResumed && workoutSettings.autoPause {
                print("Auto Resume")
                resumeWorkout()
            }
        }

The problem occurs into "// Auto-pause" section. Have I missed something ?


Solution

  • I have finally found what to do to handle this situation. When I receive a .motionPaused or .motionResumed event, I have to manually add .pause and .resume events to the workout builder to make the total workout time accurate. It's not explained in Apple documentation so I hope it will help other people facing the same issue. By doing this auto pause/resume is working fine:

    case .motionPaused:
                toggleSessionDisplayState(.paused)
                // manually add pause event to fix workout duration
                workoutBuilder.addWorkoutEvents([HKWorkoutEvent(type: .pause, dateInterval: DateInterval(start: Date(),duration: 0), metadata: [:])])  { (success, error) in
                    if error != nil {
                        print(error!)
                    }
                }
                os_log("Auto Pause Builder Event")
                
    case .motionResumed:
                toggleSessionDisplayState(.running)
                // manually add resume event to fix workout duration
                workoutBuilder.addWorkoutEvents([HKWorkoutEvent(type: .resume, dateInterval: DateInterval(start: Date(),duration: 0), metadata: [:])])  { (success, error) in
                    if error != nil {
                        print(error!)
                    }
                }
                os_log("Auto Resume Builder Event")