iOS
BLE
RxSwift

RxBluetoothKitでBLEデバイスへ大量のデータを送信する

RxBluetoothKitを使って、BLEデバイスへ大量のデータを送信する処理をシンプルに書いてみた。
BLEの仕様上、Characteristicへ一度にWRITEできるデータは20バイトのため、送信データは20バイト単位で分割して送信する必要がある。

開発環境

  • Xcode 9.0
  • Swift 3.2
  • RxBluetoothKit 3.1

RxBluetoothKit

https://github.com/Polidea/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デバイスからの切断処理が無いため、よしなに実装する。