I’m attempting to build a concurrency safe video compressor I can use on iOS <26 on which there are asynchronous APIs available. I’ve got the following from a combination of other posts/examples which was working fine on Swift 5.9, but I’ve just switched to Swift 6 and clearly uncovered an issue with my implementation. Any ideas?
Warning shown is Sending 'videoInput' risks causing data races
assetReader.startReading()
assetReader.startReading()
assetWriter.startSession(atSourceTime: .zero)
let videoQueue = DispatchSerialQueue(label: "videoCompression.video", qos: .userInitiated)
let videoCopier = AVAssetReaderCopier(videoOutput, input: videoInput, queue: videoQueue)
videoInput.requestMediaDataWhenReady(on: videoQueue) {
Task {
while await videoCopier.isReadyForMoreMediaData {
if await !videoCopier.copyNextSampleBuffer() {
await videoCopier.markAsFinished()
break
}
}
}
}
You’re passing videoInput into an actor which “attaches” this value to its concurrency domain, and even though you’ve correctly configured it to use the same dispatch queue as the executor, the compiler can’t statically prove that.
I think that the best solution would be to call videoInput.requestMediaDataWhenReady from the same actor — not to “just” fix this issue alone, but also because in the callback you’re creating a task that solely communicates with that actor, but has to needlessly await on it every time (potentially breaking transactionality in multiple places).
In the callback itself, once the call is inside the actor, you will have to wrap the logic in self.assumeIsolated { … } (which will pass because it’s called on the same queue that is used as the actor’s executor).
I’m certain this implementation is better but I’m still seeing the same warnings, presume since the compiler is correct in thinking that although I’m using the input/outputs only via the actor, there’s nothing stopping me from adding code at the call site which also interacts with the input/outputs off actor? How could I either improve this or tell the compiler that it currently being used in a way that is in fact safe but guard against future changes which would change that?