2017-05-29 112 views
0

我已经开始使用RxBluetoothKit,并为我们正在开发的外设提供良好的结果。它工作得很好,我可以执行我们需要的事务。用于多级蓝牙命令的RxBluetoothKit代码模式

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

Rx世界中是否存在适当的编码方式或模式来完成此操作?我对Rx一般来说是新手,并且很好奇什么可能是最简单,最干净的这种类型的实现。

谢谢。

回答

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观测可以更改为监视用户的行为,当实际开始排放的项目/停止动作应该发生。

+0

谢谢你。也许我应该做的一点是设备端的服务是UART服务,所以有两个特性 - TX和RX。在这种情况下,我用TX上的适当命令数据写入值,然后监视结果的RX。我很好奇的是如何在写入TX之后干净地监视RX,然后恰当地处理ACK(或NACK或错误),然后在启动之后继续执行任何命令。从我的例子中可以看出,批处理从'start'开始到'ack',其中'ack'被监控。但是在“停止”之前监视值更新块吗? – bleeckerj