У меня есть ble
сканер, который работает и выглядит следующим образом:
func scan(serviceId: String) -> Observable<[BleHandler.BlePeripheral]> {
knownDevices = []
return waitForBluetooth()
.flatMap { _ in self.scanForPeripheral(serviceId: serviceId) }
.map { _ in self.knownDevices }
}
private func waitForBluetooth() -> Observable<BluetoothState> {
return self.manager
.observeState()
.startWith(self.manager.state)
.filter { $0 == .poweredOn }
.take(1)
}
Затем в viewModel
class
он фильтрует совпадения из core data
:
func scanAndFilter() -> Observable<[LocalDoorCoreDataObject]> {
let persistingDoors: [LocalDoorCoreDataObject] = coreDataHandler.fetchAll(fetchRequest: NSFetchRequest<LocalDoorCoreDataObject>(entityName: "LocalDoorCoreDataObject"))
return communicationService
.scanForDevices(register: false)
.map{ peripherals in
print("? THIS WILL GO ON FOR ETERNITY", peripherals.count)
self.knownDevices = peripherals
return persistingDoors
.filter { door in peripherals.contains(where: { $0.identifier.uuidString == door.dPeripheralId }) }
}
}
И в view
я хочу подключиться, когда сканирование завершится:
private func scanAndConnect(data: LocalDoorCoreDataObject) {
viewModel.scanRelay().subscribe(
onNext: {
print("?SCANNED NAME", $0.first?.dName)},
onCompleted: {
print("?COMPLETED SCAN")
self.connectToFilteredPeripheral(localDoor: data)
}).disposed(by: disposeBag)
}
Оно никогда не достигнет onCompleted
, так как будет просто сканировать вечность даже после того, как найдет и filtered
the core data
совпадение. В рамках Apple coreBluetooth
я мог бы просто позвонить manager.stopScan()
после того, как он нашел то, что я хочу, но это, похоже, не доступно для Rx
аналога. Как это работает для RxSwift