RxBluetoothKit-实现读写协议并自动断开连接

时间:2019-03-31 20:45:45

标签: core-bluetooth rx-swift rxiosble

我正在中央(iPhone)和外围设备(自定义设备)之间实现BLE协议。该协议的工作方式如下:

  1. 中央连接到外围设备并设置通知
  2. 外围设备发送有关通知特征的数据
  3. 中央处理数据并在单独的特征上发送响应
  4. 外围设备发送有关通知特征的附加数据
  5. 中央过程数据并断开连接。

我正在尝试使用RxBluetoothKit以一种干净的方式实现这一点。目前可以使用,但我想解决以下挑战:

  1. 在第5步中完全断开连接的最佳方法是什么。我希望不必处理整个可观察对象,而只是使其“完成”。我目前正在使用“ takeUntil”,但不确定这是否是最好的方法。

  2. 允许通知在断开连接之前正常清理。使用我当前的代码,我会收到“ API MISUSE仅在处于连接状态时才能接受命令”,因为我相信在断开连接发生时通知会清除。

谢谢。

enum TestPeripheralService: String, ServiceIdentifier {

    case main = "CED916FA-6692-4A12-87D5-6F2764762B23"

    var uuid: CBUUID { return CBUUID(string: self.rawValue) }
}

enum TestPeripheralCharacteristic: String, CharacteristicIdentifier {

    case writer = "CED927B4-6692-4A12-87D5-6F2764762B2A"
    case reader = "CED9D5D8-6692-4A12-87D5-6F2764762B2A"

    var uuid: CBUUID { return CBUUID(string: self.rawValue) }

    var service: ServiceIdentifier { return TestPeripheralService.main }
}

fileprivate lazy var centralManager: CentralManager = {
    RxBluetoothKitLog.setLogLevel(.verbose)
    return CentralManager(queue: .main)
}()

func executeConnectionAndHandshake() {

    let disconnectSubject = PublishSubject<Bool>.init()
    var peripheral: Peripheral?
    var packetNum = 0
    _ = centralManager
        .observeState()
        .startWith(centralManager.state)
        .filter { $0 == .poweredOn }
        .flatMap { _ in self.centralManager.scanForPeripherals(withServices: [TestPeripheralService.main.uuid]) }
        .flatMap { $0.peripheral.establishConnection().takeUntil(disconnectSubject) }
        .do(onNext: { peripheral = $0 })
        .flatMap { $0.discoverServices([TestPeripheralService.main.uuid])}
        .flatMap { $0[0].discoverCharacteristics(nil)}
        .flatMap { _ in

            Observable<Bool>.create { event in

                let disposables = CompositeDisposable()
                let readSubject = PublishSubject<Data>.init()
                _ = disposables.insert(peripheral!.observeValueUpdateAndSetNotification(for: TestPeripheralCharacteristic.reader)
                    .subscribe(onNext: {
                        packetNum += 1
                        let packet = $0.value!
                        if (packetNum <= 1) {
                            readSubject.onNext(packet)
                        } else {
                            event.onNext(true)
                            event.onCompleted()
                        }

                    }, onError: { event.onError($0) })
                )

                _ = disposables.insert(readSubject
                    .flatMapLatest { data -> Single<Characteristic> in
                        var writeData = Data(capacity: 300)
                        for _ in 0..<300 {
                            writeData.append(0xFF)
                        }
                        return peripheral!.writeValue(writeData, for: TestPeripheralCharacteristic.writer, type: .withResponse)
                    }
                    .subscribe(onError: { event.onError($0) })
                )

                return Disposables.create {
                    disposables.dispose()
                }
            }
            .do(onCompleted: { disconnectSubject.onNext(true) })
        }
        .subscribe(onError: { print($0) },
                   onCompleted: { print("Connection and handshake completed") })
}

0 个答案:

没有答案