2016-08-29 115 views
2

我正嘗試使用RXBluetoothKit快速連接BLE設備。該裝置的所有數據的命令遵循以下順序 1.寫的命令(writeWithResponse) 2.閱讀來自通知的響應(在不同的特性)如何結合寫入特徵和特徵通知使用RXBluetoothKit for RxSwift

通知數據包的數量(20個字節中最大的通知數據包)將取決於命令。這將是一個固定的數字或基本上用notif值中的數據結束位表示。

這可以使用writeValue(),monitorValueUpdate()組合來實現嗎?

回答

2
// Abstraction of your commands/results 
enum Command { 
    case Command1(arg: Float) 
    case Command2(arg: Int, arg2: Int) 
} 

struct CommandResult { 
    let command: Command 
    let data: NSData 
} 

extension Command { 
    func toByteCommand() -> NSData { 
     return NSData() 
    } 
} 

// Make sure to setup notifications before subscribing to returned observable!!! 
func processCommand(notifyCharacteristic: Characteristic, 
        _ writeCharacteristic: Characteristic, 
        _ command: Command) -> Observable<CommandResult> { 

    // This observable will take care of accumulating data received from notifications 
    let result = notifyCharacteristic.monitorValueUpdate() 
     .takeWhile { characteristic in 
      // Your logic which know when to stop reading notifications. 
      return true 
     } 
     .reduce(NSMutableData(), accumulator: { (data, characteristic) -> NSMutableData in 
      // Your custom code to append data? 
      if let packetData = characteristic.value { 
       data.appendData(packetData) 
      } 
      return data 
     }) 

    // Your code for sending commands, flatmap with more commands if needed or do something similar 
    let query = writeCharacteristic.writeValue(command.toByteCommand(), type: .WithResponse) 

    return Observable.zip(result, query, resultSelector: { (result: NSMutableData, query: Characteristic) -> CommandResult in 
     // This block will be called after query is executed and correct result is collected. 
     // You can now return some command specific result. 

     return CommandResult(command: command, data: result) 
    }) 
} 

// If you would like to serialize multiple commands, you can do for example: 
func processMultipleCommands(notifyCharacteristic: Characteristic, 
          writeCharacteristic: Characteristic, 
          commands: [Command]) -> Observable<()> { 
    return Observable.from(Observable.just(commands)) 
     // concatMap would be more appropriate, because in theory we should wait for 
     // flatmap result before processing next command. It's not available in RxSwift yet. 
     .flatMap { command in 
      return processCommand(notifyCharacteristic, writeCharacteristic, command) 
     } 
     .map { result in 
      return() 
     } 
} 

你可以試試以上。這只是一個想法,你可以如何處理它。我試圖評論最重要的事情。請讓我知道這對你有沒有用。