Hey,
I'm stuck for a while now and I kindly ask for some help.
I want to scan for BT-peripherals with a specific name and provide those in a list to use in SwiftUI.
My current (somehow working) approach is this:
class BT public class API: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate, ObservableObject {
@Published var discoveredDevices = [CBPeripheral]()
public func scan(timeout: Double, completion: @escaping (([CBPeripheral]) -> Void))
{
guard connectionState == STATE.DISCONNECTED else {
print ("Can only start scan from DISCONNECTED")
return
}
discoveredDevices = []
let options: [String: Any] = [CBCentralManagerScanOptionAllowDuplicatesKey: NSNumber(value: false)]
centralManager.scanForPeripherals(withServices: nil, options: options)
DispatchQueue.main.asyncAfter(deadline: .now() + timeout) {
self.stopScan()
completion(self. discoveredDevices)
}
}
public func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
peripheral.delegate = self
if (peripheral.name?.contains("testDevice") ?? false) {
discoveredDevices.append(peripheral)
}
}
}
But I am not happy with that. I would like to use async/await in the scan-function and return the list, so I can use something like this in SwiftUI:
let devices = try await scan(timeout:5)
I tried around a lot already, but I cannot manage to
"collect" devices within a specified time and return those through the scan-function.
Where I cannot wrap my head around is that the delegate-method (didDiscover) gets called with every discovered device. How can I let the scan-function know when the scanning is done (timeout ran out) and only then return the list of the discovered devices?
Thanks in advance already