I want to call my actor's isolated functions from within the delegate method: nonisolated func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void)

Generated on 8/3/2024

1 search

To call your actor's isolated functions from within the delegate method nonisolated func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void), you can use the assumeIsolated method to inform the compiler that the code is already running on the main actor. This approach avoids starting a new task to async onto the main actor.

Here's a relevant excerpt from the session "Migrate your app to Swift 6":

When you know for certain that a call will be on a particular actor, there's a method you can use to tell the compiler this. It's called assumeIsolated. So instead of the code starting a task, you can write MainActor.assumeIsolated. This doesn't start a new task to async onto the main actor; it just tells Swift that this code is already running on the main actor. Note that it's still perfectly possible for some part of the code to call this function from not the main actor. This is the same as with Swift functions today that assume they're being called from the main thread. A good way to protect against this is to add an assertion inside the function that you are indeed on the main actor, and that's what assumeIsolated does. If this function is ever not called from the main actor, it will trap and your code will stop running. Trapping isn't something you want, but it's better than a race condition that could corrupt users' data. Now this pattern of conforming to a delegate protocol that assumes it's called on the main actor is common enough that there's a shorthand for it.

For more details, you can refer to the session Migrate your app to Swift 6 (24:15).