RxBluetoothKitを使って、BLEデバイスへ大量のデータを送信する処理をシンプルに書いてみた。
BLEの仕様上、Characteristicへ一度にWRITEできるデータは20バイトのため、送信データは20バイト単位で分割して送信する必要がある。
開発環境
- Xcode 9.0
- Swift 3.2
- RxBluetoothKit 3.1
RxBluetoothKit
BLEデバイスをスキャンする
func scan() -> Observable<Peripheral> {
let manager = BluetoothManager(queue: .main)
return manager.rx_state
.filter { $0 == .poweredOn }
.flatMap { _ in manager.scanForPeripherals(withServices: [SERVICE_UUID]) } // SERVICE_UUIDは任意
}
BLEデバイスへ接続し、バイナリデータ(Data型のArray)を任意のCharacteristicへWRITEする
func connectWithWriteData(peripheral: Peripheral, data: [Data]) -> Observable<Characteristic> {
return peripheral.connect()
.flatMap { $0.discoverServices([SERVICE_UUID]) } // SERVICE_UUIDは任意
.flatMap { Observable.from($0) }
.flatMap { $0.discoverCharacteristics([CHARACTERISTIC_UUID]) } // CHARACTERISTIC_UUIDは任意
.flatMap { Observable.from($0) }
.flatMap { Observable.combineLatest(Observable.just($0), Observable.from(data)) } // ★重要
.flatMap { $0.writeValue($1, type: .withoutResponse) }
}
使い方
let disposeBag = DisposeBag()
func hoge() {
let data = createWriteData() // 20バイト単位で分割したバイナリデータ(Data型のArray)を用意する
scan()
.flatMap { $0.connectWithWriteData(peripheral: $0, data: data) }
.subscribe(onCompleted: {
print("write completed!!")
}, onError: {
print("write error!!")
})
.addDisposableTo(disposeBag)
}
注意
- 上記実装の場合、SERVICE_UUIDが一致するBLEデバイスへ片っ端から接続しに行くため、take(n)等でよしなに接続数を絞る。
- 各処理にタイムアウトが設けられていないため、よしなに設定する。
- BLEデバイスからの切断処理が無いため、よしなに実装する。