Post

Replies

Boosts

Views

Activity

When do the HKWorkoutBuilder.finishWorkout() returns nil ?
I use the following code : do { ...       Logger.health.info(c: .saveWorkout, "Ending collection.")       try await builder.endCollection(at: workout.end)       Logger.health.info(c: .saveWorkout, "Finishing workout.")       let hkFinishedWorkout = try await builder.finishWorkout()       guard let hkworkout = hkFinishedWorkout else {         Logger.health.error(c: .saveWorkout, "Error finishing workout. Returned workout is nil!")         return false       } ... } catch {       Logger.health.error(c: .saveWorkout, "Failed to save workout: \(String(describing: error))")       return false } This code sometimes behave correctly, but it also happen to log "Error finishing workout. Returned workout is nil!" which indicates that the builder.finishWorkout() returned nil without throwing an error. Notes: There is a workout session running in parallel on the AppleWatch. The workout is correctly saved, but all the location information is missing as the route builder needs the workout to be saved. My question is when do finishWorkout()returns nil without throwing an error ?
1
0
1.3k
Dec ’21
How to save a workout with a route on a locked iPhone ?
This question is a follow-up of https://developer.apple.com/forums/thread/695853 I need to save a workout with a route from a locked iPhone. I've tried many different ways of saving it since more than one year but I still struggle to find a code which works when the phone is locked. My current code is :       let healthStore = HKHealthStore()       let workoutConfiguration = HKWorkoutConfiguration() workoutConfiguration.activityType = .running       let builder = HKWorkoutBuilder(healthStore: healthStore,                                       configuration: workoutConfiguration,                                       device: .local())       try await builder.beginCollection(at: workout.start)       guard let quantityType = HKQuantityType.quantityType(forIdentifier: .activeEnergyBurned) else { ... }       let totalEnergyBurnedSample = HKCumulativeQuantitySample(type: quantityType, quantity: HKQuantity(unit: HKUnit.kilocalorie(), doubleValue: totalEnergyBurned), start: workout.start, end: workout.end)       try await builder.addSamples([totalEnergyBurnedSample])       if let route = builder.seriesBuilder(for: .workoutRoute()) as? HKWorkoutRouteBuilder {         try await route.insertRouteData(locations)       } else {         Logger.health.error("Error creating the route builder! Skipping location addition to HealthKit workout.")       }       try await builder.endCollection(at: workout.end)       let hkFinishedWorkout = try await builder.finishWorkout()       Logger.health.info("Workout saved successfully.")     } catch {       Logger.health.error("Failed to save workout: \(String(describing: error))")     } I naively though that by getting the HKWorkoutRouteBuilder from the HKWorkoutBuilder, the finishWorkout() method would link both of them, but this code never reports an error and the route is associated with the workout only when the iPhone is unlocked when saving. If this code is executed on a locked iPhone, the workout is created, the route is created (both can be seen in the Health application) but the route is not associated with the workout. I can't call finishRoute(with: hkworkout, metadata: nil) on the HKWorkoutRouteBuilder as it requires the HKWorkout which the HKWorkoutBuilder does not return when the phone is locked ;-( Is there a way to create a workout with an associated route on a locked iPhone ?
3
0
1.4k
Dec ’21