我正在通过CoreBluetooth向BLE设备发送一个大的二进制文件以更新设备上的固件。但是,我遇到了一个问题,即CoreBluetooth没有限制写入速率,并且发送消息的速度太快,设备无法全部接收。要确保CoreBluetooth等待足够长的时间,以便确保发送所有消息(而不冻结UI队列),最好的方法是什么?
我的当前代码是:
private func sendOTAUpgrade(data: [UInt8], complete: @escaping () -> Void) {
let packets = makePackets(size: 20, arr: data)
var count = 0
for packet in packets {
firmwareUpgradePercentComplete = Double(count)/Double(packets.count)
print("Sent packet - \(firmwareUpgradePercentComplete*100)% complete")
let data = NSData(bytes: packet, length: 20)
self.connectedPeripheral?.writeValue(data as Data, for: self.otcDataCharacteristic!, type: CBCharacteristicWriteType.withoutResponse)
count += 1
}
complete()
}
2条答案
按热度按时间mw3dktmi1#
有多种方法。如果你想坚持使用
.withoutResponse
,你应该检查canSendWriteWithoutResponse
,如果这个属性为真,你可以再写一次。如果为假,你需要等到peripheralIsReady
被调用。有了它,你应该能够写一些可靠的数据.
CoreBluetooth WWDC 2017会议的新功能
今年,我们使用一个名为canSendWriteWithoutResponse的新属性增强了CBPeripheral。
如果您在执行写入操作之前调用此函数,并且它返回yes,则表示我们向您承诺,在我们有机会将数据发送到远程外设之前,您的数据不会在软件中丢失。
如果返回no,那么当我们准备好的时候,你也会得到一个委托回调,我们会回调peripheralIsReady
根据你的目标,你可能需要在你的外设中实现一些流量控制。如果这不可能,可能有一个实用的解决方案来检查你的设备可以处理多少数据。所以队列可以帮助你在发送时获得一些控制,而不必切换到.writeWithResponse
wkftcu5l2#
执行写入而不响应,在每次中央写入时包括序列索引号,并在外围设备接收到每次写入后发送回包含传输状态的通知,即回送最新序列号或顺序错误的序列号。在中央设备发送最终写入后,等待外围设备发送最终写入的序列号。