Created
August 17, 2017 16:53
-
-
Save jwhitley/5925f89ceba2520a6b322b3dbdeaf732 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is a "rough sketch" pulled from our application that shows how we use | |
// RxBluetoothKit and Nordic's DFU library together. It's more than | |
// pseudocode, yet not standalone, rigorously tested running code. A lot of | |
// details are simplified or omitted here, e.g. any device-specific details | |
// you may require, implementations for Nordic's DFU delegate protcols, etc. | |
import iOSDFULibrary // Nordic's DFU Library | |
import RxBluetoothKit | |
enum ExampleDeviceService: String, ServiceIdentifier { | |
case dfuUpdateService = "YOUR-DFU-GUID-GOES-HERE" | |
} | |
class FirmwareUpdater { | |
private let manager: BluetoothManager | |
static let dfuScanTimeout: RxTimeInterval = 10 | |
lazy var dfuTimeoutScheduler: ConcurrentDispatchQueueScheduler = | |
ConcurrentDispatchQueueScheduler(queue: DispatchQueue(label: "com.example.rxbluetooth.timer")) | |
init() { | |
// We've found it best to create a separate BluetoothManager instance for | |
// each DFU activity to prevent a number of problems with non-DFU | |
// activities, e.g. scanning for and communicating with devices in normal | |
// usage may go wonky due to the CBCentralManager getting into an odd state. | |
self.manager = BluetoothManager(queue: .main, options: [ | |
CBCentralManagerOptionRestoreIdentifierKey: "ExampleDFUCentralManager" as NSString | |
]) | |
} | |
private func waitForBLE() -> Observable<BluetoothManager> { | |
return self.manager.rx_state | |
.filter { $0 == .poweredOn } | |
.take(1) | |
.map { _ in self.manager } | |
} | |
func updateBand(_ selectedFirmware: DFUFirmware) -> Observable<Void> { | |
var dfuScan = self.waitForBLE() | |
.flatMap { $0.scanForPeripherals(withServices: [ExampleDeviceService.dfuUpdateService.uuid], options:nil) } | |
.take(FirmwareUpdater.dfuScanTimeout, scheduler: dfuTimeoutScheduler) | |
return dfuScan | |
.subscribeOn(MainScheduler.instance) | |
.flatMap { scannedPeripheral -> Observable<Void> in | |
// We've let RxBluetoothKit handle the BLE workflow up to this point. | |
// Now extract the CBCentralManager and CBPeripheral and hand those off | |
// to Nordic's DFU library to initiate and complete the DFU process. | |
let centralManager = scannedPeripheral.peripheral.cbCentralManager | |
let peripheral = scannedPeripheral.peripheral.cbPeripheral | |
let initiator = DFUServiceInitiator(centralManager: centralManager, target: peripheral).with(firmware: selectedFirmware) | |
initiator.logger = self.delegate | |
initiator.delegate = self.delegate | |
initiator.progressDelegate = self.delegate | |
self.controller = initiator.start() | |
return Observable.just(()) | |
} | |
} | |
} | |
extension FirmwareUpdater: LoggerDelegate, DFUServiceDelegate, DFUProgressDelegate { | |
// ... implementations for Nordic's DFU delegate protocols ... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment