Search code examples
swiftuiwatchoshealthkit

Watch falls asleep during active HKWorkoutSession


I get data from the accelerometer (CMMotionManager) and training (HKWorkoutSession) and transfer it to the phone in real time, but at a random moment the watch falls asleep.

In the info I use WKBackgroundModes: workout-processing The strap is tightened tightly, at first I thought that he was losing contact and the reason was in it. When I wrote the same functions earlier using WatchKit, there was no such problem, but now with SwiftUI there is this a problem.

do {
   let workoutConfiguration = HKWorkoutConfiguration()
   workoutConfiguration.activityType = .mindAndBody
   workoutConfiguration.locationType = .unknown
   self.session = try HKWorkoutSession(healthStore: self.healthStore, configuration: workoutConfiguration)
   self.builder = self.session?.associatedWorkoutBuilder()
   self.builder?.dataSource = HKLiveWorkoutDataSource(healthStore: self.healthStore, workoutConfiguration: workoutConfiguration)
   self.session?.delegate = self
   self.builder?.delegate = self
   // timer for update state
   self.timerHealth = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.getHealth), userInfo: nil, repeats: true)
   self.session?.startActivity(with: self.startDate)
   self.builder?.beginCollection(withStart: self.startDate) { (success, error) in
      guard success else {
          print(error?.localizedDescription)
          return
      }
    }
} catch {
   print(error.localizedDescription)
   return
}

The timer print the current time, at a random moment the output stops and is restored only after the screen is turned on

Apple's documentation write that if the workout process is enabled, the application will continue in the background, but it is not. How to set up background work? What did I miss?


Solution

  • You could get suspended when running in background if your app uses a lot of CPU. See https://developer.apple.com/documentation/healthkit/workouts_and_activity_rings/running_workout_sessions

    To maintain high performance on Apple Watch, you must limit the amount of work your app performs in the background. If your app uses an excessive amount of CPU while in the background, watchOS may suspend it. Use Xcode’s CPU report tool or the time profiler in Instruments to test your app’s CPU usage. The system also generates a log with a backtrace whenever it terminates your app.

    It would be good to check if your SwiftUI app is doing more work than your WatchKit based one causing the suspension. You should also see a log file saved on watch that could indicate this. It'll look like a crash log but should note that CPU time was exceeded.