如何使用 RxSwift 的 RXBluetoothKit 结合写入特性和特性通知

Posted

技术标签:

【中文标题】如何使用 RxSwift 的 RXBluetoothKit 结合写入特性和特性通知【英文标题】:How to combine write characteristics and charcteristics notify using RXBluetoothKit for RxSwift 【发布时间】:2016-08-29 12:41:16 【问题描述】:

我正在尝试使用 RXBluetoothKit 快速连接 BLE 设备。设备的所有数据命令遵循以下顺序 1.写一个命令(writeWithResponse) 2.阅读通知的响应(关于不同的特征)

通知包的数量(通知包中最多 20 个字节)将取决于命令。这将是一个固定数字,或者本质上使用通知值中的数据结束位来指示。

这可以使用writeValue()、monitorValueUpdate()组合实现吗?

【问题讨论】:

【参考方案1】:
// 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 ()
        

你可以试试上面的。这只是一个想法,你可以如何处理它。我试图评论最重要的事情。让我知道它是否适合你。

【讨论】:

以上是关于如何使用 RxSwift 的 RXBluetoothKit 结合写入特性和特性通知的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift,如何更温和地使用 NotificationCenter?

RxSwift 以及如何制作简单的 TableViewController?

如何使用 RxSwift 处理应用程序状态

如何正确安装“RxSwift”模块?

如何使用 RxSwift 为空 tableView 显示 backgroundVIew

如何使用 RxSwift 观察 UITextField 中的文本变化?