用于多级蓝牙命令的RxBluetoothKit代码模式

时间:2017-05-29 16:55:12

标签: swift rx-swift rxiosble

我已经开始使用RxBluetoothKit,对我们正在开发的外设有很好的效果。它运作良好,我能够执行我们需要的交易。

我有一个设计模式问题。我们有几个命令,其中我们的API包括多步命令。例如,应用程序写入命令启动代码,外围设备用ACK确认,然后应用程序写入命令,等待ACK,发出另一个命令,等待另一个ACK等。这可以继续,直到应用程序发出命令停止代码,例如,当用户告诉应用程序停止时,它将在未来某个不确定的位置。

在Rx世界中是否有适当的编码习惯用法或模式来实现这一目标?我一般都是Rx的新手,很好奇这可能是最简单,最干净的实现。

感谢。

1 个答案:

答案 0 :(得分:1)

详细信息始终取决于您的具体用例。我喜欢将Rx视为基于流的构建块,需要将其连接起来为您的业务逻辑建模。

有一个例子如下:

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)

在那里,可以更改startstop可观察量以监控用户的行为,并在实际开始/停止操作发生时发出项目。