HKWorkoutSessionDelegate lap events consistently delayed

I'm building a swimming workout app for watchOS, and while testing in the pool we're seeing a consistent 1 lap delay on the delivery of lap event data to the HKWorkoutSession's delegate. That is, when the user does their turn at the end of lap 2, the delegate receives an event for lap 1. Sometimes the delays are longer, but they are never shorter than 1 lap. We're determining this delay by logging the receive time of the event (ie, when the delegate method was called), along with the start and end times of the event's dateInterval. This has been confirmed by correlating those logs with the logs of an observer on the deck of the pool logging when the swimmer did their turns.


I've read the documentation on HKWorkoutSession multiple times, and watched all the WWDC sessions I can find about workouts, and can't figure out what could be causing this delay. Has anyone seen this sort of behavior? Any tips on fixing it?


Here's my workout session startup code. As far as I can tell it's doing nothing substantively different than the example apps from Apple:


     func createSession(poolLength: Measurement<UnitLength>) throws -> WorkoutSession {
        let config = HKWorkoutConfiguration()
        config.activityType = .swimming
        config.swimmingLocationType = .pool
        // I added an extension on UnitType to convert to HKUnits
        config.lapLength = HKQuantity(unit: poolLength.unit.asHKUnit, doubleValue: poolLength.value)
        configuration = config
        
        let session = try HKWorkoutSession(healthStore: store, configuration: config)
        let builder = session.associatedWorkoutBuilder()
        
        builder.delegate = self
        builder.dataSource = HKLiveWorkoutDataSource(healthStore: store, workoutConfiguration: config)
        
        workoutBuilder = builder
        
        session.startActivity(with: Date())
        // Collected does logging in this app
        Collected.workoutStart.saveToDatabase()
        builder.beginCollection(withStart: Date(), completion: { completed, error in
            print("Builder began collection: \(completed)")
            if let e = error {
                Collected.workoutError(error: e).saveToDatabase()
                print("Builder error: \(e)")
            }
        })
        
        // This is a wrapper class which acts as the delegate for the HKWorkoutSession
        return WorkoutSession(session)
    }

Replies

Have you found any solution to this problem?