ios – Concurrency points with HKLiveWorkoutBuilder managed by @Observable class

0
21
ios – Concurrency points with HKLiveWorkoutBuilder managed by @Observable class


The issue is that builder and session are remoted to the MainActor however not Sendable. You can’t name nonisolated async strategies on it as a result of that may find yourself sending it off the primary actor.

It’s best to name beginCollection in a non-isolated technique, so there are not any actor hops that sends non-sendable values. It’s best to solely assign the builder and session again to the occasion properties (sending them again to the primary actor) after you might be accomplished with them. Because of region-based isolation, Swift understands that that is your final time utilizing the builder and session within the non-isolated technique, so they’re protected to be despatched off.

If you happen to ship them again to the primary actor earlier than that, you might be basically sharing the occasion between the primary actor and the non-isolated code after that, which in fact will not be protected with non-sendable values.

// major actor remoted model so as to simply name from a view
func startWatchWorkout(_ identify: String, _ startDate: Date) async {
    await startWatchWorkoutImpl(identify, startDate)
}

non-public nonisolated func startWatchWorkoutImpl(_ identify: String, _ startDate: Date) async {
    do {
        let configuration = HKWorkoutConfiguration()
        configuration.activityType = .traditionalStrengthTraining
        // be aware that I'm not assigning to self.session and self.builder right here
        let session = attempt HKWorkoutSession.make(healthStore: retailer, configuration: configuration)
        let builder = session?.associatedWorkoutBuilder()
        builder?.dataSource = HKLiveWorkoutDataSource(healthStore: retailer, workoutConfiguration: configuration)
        session?.startActivity(with: startDate)
        attempt await builder?.beginCollection(at: startDate)
        await setSessionAndBuilder(session, builder)
    } catch {
        // ...
    }
}

// assigning the properties needs to be accomplished in a major actor remoted context
non-public func setSessionAndBuilder(_ s: HKWorkoutSession?, _ b: HKLiveWorkoutBuilder?) {
    session = s
    builder = b
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here