The following class from AVCam sample code generates error in Swift 6 Task-isolated 'newDevice' is passed as a 'sending' parameter; Uses in callee may race with later task-isolated uses
.
The error happens in the line continuation?.yield(newDevice)
. I suspect it has to do with AVCaptureDevice
not being Sendable
. But the error talks about keyword sending
which I have come across multiple times but never saw its definition.
@preconcurrency import AVFoundation
/// An object that provides an asynchronous stream capture devices that represent the system-preferred camera.
class SystemPreferredCameraObserver: NSObject {
private let systemPreferredKeyPath = "systemPreferredCamera"
let changes: AsyncStream<AVCaptureDevice?>
private var continuation: AsyncStream<AVCaptureDevice?>.Continuation?
override init() {
let (changes, continuation) = AsyncStream.makeStream(of: AVCaptureDevice?.self)
self.changes = changes
self.continuation = continuation
super.init()
/// Key-value observe the `systemPreferredCamera` class property on `AVCaptureDevice`.
AVCaptureDevice.self.addObserver(self, forKeyPath: systemPreferredKeyPath, options: [.new], context: nil)
}
deinit {
continuation?.finish()
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
switch keyPath {
case systemPreferredKeyPath:
// Update the observer's system-preferred camera value.
let newDevice = change?[.newKey] as? AVCaptureDevice
continuation?.yield(newDevice)
default:
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
}
The error goes away if I add this line in the code:
extension AVCaptureDevice: @unchecked @retroactive Sendable {
}
I just want to understand what's exactly going on here and if my fix is alright.