HKWorkoutBuilder state machine issue with discardWorkout()

When I call the discardWorkout() method on either HKLiveWorkoutBuilder or HKWorkoutBuilder when a user wants to trash a workout, I'm seeing logs emmitted from HealthKit with invalid state transitions.


The language of the documentation says discardWorkout() "Stops the collection of data and discards the current results without saving the workout." Reading into the language, I assume you don't need to call endCollection(..) which "Stops the collection of data, sets the workout’s end date, and deactivates the workout builder."


When discardWorkout() is called after beginCollection the following is produced:


WatchKit Extension[12936:1162537] [workouts] HKLiveWorkoutBuilder_6464 [2AA9]: (#w0) Failed to update target construction state: Error Domain=com.apple.healthkit Code=3 "Unable to handle event 4 from state Active(1); valid transitions are: {

100 = "<error(100): Active(1) -> Error(6)>";

2 = "<end(2): Active(1) -> AwaitingFinalData(2)>"; // This one looks like what its calling for.

3 = "<finish(3): Active(1) -> AwaitingFinalData(2)>";

}" UserInfo={NSLocalizedDescription=Unable to handle event 4 from state Active(1); valid transitions are: {

100 = "<error(100): Active(1) -> Error(6)>";

2 = "<end(2): Active(1) -> AwaitingFinalData(2)>";

3 = "<finish(3): Active(1) -> AwaitingFinalData(2)>";

}}


Decyphering that, looks like builder has internal state called active and wants transition to end (call end collection).


Ending collection before discarding gets this instead:


WatchKit Extension[13058:1169802] [workouts] HKLiveWorkoutBuilder_827D [2A5A]: (#w0) Failed to update target construction state: Error Domain=com.apple.healthkit Code=3 "Unable to handle event 4 from state Ended(3); valid transitions are: {

100 = "<error(100): Ended(3) -> Error(6)>";

3 = "<finish(3): Ended(3) -> Saving(4)>"; // But I don't want to finish the workout, I want to discard it!

}" UserInfo={NSLocalizedDescription=Unable to handle event 4 from state Ended(3); valid transitions are: {

100 = "<error(100): Ended(3) -> Error(6)>";

3 = "<finish(3): Ended(3) -> Saving(4)>";

}}


I've tried on watchOS 5.1 and iOS 12.1 same thing. Has anyone had success calling discardWorkout without getting state machine logs like this emitted over console?


It feels like it is working and the previous workoutSession and builder are being disposed just fine when a new session occurrs. Maybe its a false positive error.

Replies

Did you ever solve this problem? I'm having the same issue.


I tried calling workoutBuilder.endCollection() before discarding the session, but I received a different state error.


I also tried endCollection() then finishWorkout(), then discarding, but that also didn't work.


However, even though I received the error, the workout was discarded.