RxBluetoothKit Code Pattern for Multiple Stage Bluetooth Commands

旧城冷巷雨未停 提交于 2019-12-12 04:14:22

问题


I've started using RxBluetoothKit with good results for a peripheral we are developing. It works quite well and I am able to perform the transactions we need.

I have a design pattern question. We have a couple of commands where our API includes multi-step commands. For example, the App writes a command start code, the Peripheral confirms with an ACK, then the App writes the command, waits for an ACK, issues another command, waits for another ACK, etc. This can go on until the App issues a command stop code, which will be at some indeterminate point in the future — when the user tells the app to stop, for example.

Is there an appropriate coding idiom or pattern in the Rx world for accomplishing this? I am new to Rx in general, and am curious what might be the simplest, cleanest implementation of something of this sort.

Thanks.


回答1:


Details as always depend on your very specific use case. I like to think about Rx as stream based building blocks which needs to be connected to model your business logic.

There is one example how it may look like:

enum DeviceService: String, ServiceIdentifier {
    case myService = "ffff"

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

enum DeviceCharacteristic: String, CharacteristicIdentifier {
    case startCharacteristic = "0001"
    case stopCharacteristic = "0002"
    case ackCharacteristic = "ffff"
    case command1Characteristic = "0003"
    case command2Characteristic = "0004"

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

    var service: ServiceIdentifier {
        return DeviceService.myService
    }
}

let peripheral : Peripheral? = nil

// Some internal command 1
let command1 = peripheral!.writeValue(Data(bytes: [0xff, 0xfe]),
                                      for: DeviceCharacteristic.command1Characteristic,
                                      type: .withResponse)

// Some internal command 2
let command2 = peripheral!.writeValue(Data(bytes: [0xdd, 0xee]),
                                      for: DeviceCharacteristic.command2Characteristic,
                                      type: .withResponse)

func batchCommands(commands: [Observable<Characteristic>]) -> Observable<Characteristic> {

    let commandsWithAck = commands.map { command in
        return command.flatMap { characteristic in
            return peripheral!.monitorValueUpdate(for: DeviceCharacteristic.ackCharacteristic).take(1)
        }
    }

    let start = peripheral!.writeValue(Data(bytes: [0x01]),
                                            for: DeviceCharacteristic.startCharacteristic,
                                            type: .withResponse)
    let stop = peripheral!.writeValue(Data(bytes: [0x00]),
                                           for: DeviceCharacteristic.startCharacteristic,
                                           type: .withResponse)

    return start.concat(Observable.concat(commandsWithAck)).concat(stop)
}

// Call it:
let subscription = batchCommands(commands: [command1, command2])
    .subscribe(onNext: nil, onError: nil, onCompleted: nil, onDisposed: nil)

There, start and stop observables can be changed to monitor user's behaviour and emit items when actual start/stop action should took place.



来源:https://stackoverflow.com/questions/44247320/rxbluetoothkit-code-pattern-for-multiple-stage-bluetooth-commands

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!