Eu estava lendo este blog, pois tenho um caso de uso semelhante: https://kelvas09.github.io/blog/posts/closure-delegate-to-async/
Notei o seguinte trecho:
actor BluetoothLEScanWrapper {
enum BluetoothLEScanError: Error {
case bluetoothNotAvailable
}
private let bluetoothLEDelegate: BluetoothLEDelegate = BluetoothLEDelegate()
private var activeTask: Task<[BluetoothLEDevice], Error>?
func scan(for seconds: Double = 3.0) async throws -> [BluetoothLEDevice] {
if let existingTask = activeTask {
return try await existingTask.value
}
let task = Task<[BluetoothLEDevice], Error> {
guard bluetoothLEDelegate.bluetoothIsOn else {
activeTask = nil
throw BluetoothLEScanError.bluetoothNotAvailable
}
self.bluetoothLEDelegate.central.scanForPeripherals(withServices: nil)
try await Task.sleep(nanoseconds: (UInt64(seconds) * 1_000_000_000))
let devices = bluetoothLEDelegate.foundPeripheral.compactMap { BluetoothLEDevice(peripheral: $0) }
bluetoothLEDelegate.central.stopScan()
bluetoothLEDelegate.foundPeripheral = []
activeTask = nil
return devices
}
activeTask = task
return try await task.value
}
...
O autor chama especificamente a atenção para o uso do ator. Pelo que entendi, isso é para evitar corridas de dados activeTask
caso scan()
seja chamado repetidamente. Meu entendimento está correto? Obrigado pela ajuda.