2017-05-29 117 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