How to fix this Swift 6 migration issue?

Here is a code snippet about AVPlayer.

avPlayer.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 60), queue: .main) { [weak self] _ in
    // Call main actor-isolated instance methods
}

Xcode shows warnings that Call to main actor-isolated instance method '***' in a synchronous nonisolated context; this is an error in the Swift 6 language mode. How can I fix this?

avPlayer.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 60), queue: .main) { [weak self] _ in
     Task { @MainActor in
         // Call main actor-isolated instance methods
     }
}

Can I use this solution above? But it seems switching actors frequently can slow down performance.

Answered by DTS Engineer in 804156022

Note how addPeriodicTimeObserver(…) takes a queue parameter which tells the system the queue on which to run the observer. You’re passing .main, indicating that you want the observer to run on the main queue. In that case, you don’t need to spin up a task. Rather, you can use assumeIsolate(…), which has two functions:

  • At compile time, it tells the compiler that you’re expecting this code to run on the main actor.

  • At runtime, it checks that fact.

So, your code might look like this:

avPlayer.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 60), queue: .main) { [weak self] _ in
    MainActor.assumeIsolated {
        self?.myMainActorIsolatedMethod()
    }
}

There are a bunch of recipes like this in the Migrating to Swift 6 doc.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Accepted Answer

Note how addPeriodicTimeObserver(…) takes a queue parameter which tells the system the queue on which to run the observer. You’re passing .main, indicating that you want the observer to run on the main queue. In that case, you don’t need to spin up a task. Rather, you can use assumeIsolate(…), which has two functions:

  • At compile time, it tells the compiler that you’re expecting this code to run on the main actor.

  • At runtime, it checks that fact.

So, your code might look like this:

avPlayer.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 60), queue: .main) { [weak self] _ in
    MainActor.assumeIsolated {
        self?.myMainActorIsolatedMethod()
    }
}

There are a bunch of recipes like this in the Migrating to Swift 6 doc.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

How to fix this Swift 6 migration issue?
 
 
Q