Я работаю над приложением для iOS, в котором мне нужно отправить более 20 байтов данных в центральный терминал Bluetooth LE.Я установил периферийный менеджер и отправляю каждый «пакет» по 20 байт один за другим.Я отправляю следующий пакет только один раз, когда peripheralManager.updatevalue
возвращает значение true (повторная попытка после вызова peripheralManagerIsReadyToUpdateSubscribers
, если updateValue
возвращает значение false).В большинстве случаев это работает, однако примерно в 20% случаев отправляемые данные неверны.
У меня три пакета.Большую часть времени центральный получает A, затем B, а затем C, однако иногда центральный получает B, затем B, затем C или A, затем C, а затем снова C.
Он всегда отправляет три уведомления, однако значения неверны.
В случае, если это важно:
Значения для характеристики сохраняются в экземплярах BLECharacteristic
объектов
@objc public class BLECharacteristic: CBMutableCharacteristic{
public var dynamicValue: Data?
public override init(type UUID: CBUUID, properties: CBCharacteristicProperties, value: Data?, permissions: CBAttributePermissions){
super.init(type: UUID, properties: properties, value: nil, permissions: permissions)
self.dynamicValue = value
}
public convenience init(characteristic: CBCharacteristic){
self.init(type: characteristic.uuid, properties: characteristic.properties, value: characteristic.value, permissions: CBAttributePermissions.readable)
}
}
И когда уведомления «буферизируются» дляотправляется после вызова peripheralManagerIsReadyToUpdateSubscribers
, информация сохраняется в объекте * 1017. *
@objc public class DelayedNotification: NSObject{
private(set) var valueToNotify: Data
private(set) var characteristic: BLECharacteristic
private(set) var devicesToNotify: [CBCentral]?
@objc public init(_ data: Data, _ char: BLECharacteristic, _ devsNotify: [CBCentral]?){
valueToNotify = data
characteristic = char
devicesToNotify = devsNotify
}
}
Когда объект создан:
var valueToSend: Data
if(characteristic.dynamicValue == nil){
valueToSend = Data()
}else{
valueToSend = characteristic.dynamicValue!
}
buffer.append(DelayedNotification(valueToSend, characteristic, devicesToNotify))
Редактировать: Больше кода
private func notifyDevices(_ characteristic: BLECharacteristic){
DispatchQueue.main.async {
var valueToSend: Data
if(characteristic.dynamicValue == nil){
valueToSend = Data()
}else{
valueToSend = Data(characteristic.dynamicValue!)
}
self.notificationLock.wait()
self.notBuffer.append(DelayedNotification(valueToSend, characteristic, nil))
self.notificationLock.signal()
self.processNotificationBuffer()
}
}
private func processNotificationBuffer(){
DispatchQueue.main.async{
self.notificationLock.wait()
for notification in self.notBuffer{
let res = self.peripheralManager.updateValue(Data(notification.valueToNotify), for: notification.characteristic, onSubscribedCentrals: notification.devicesToNotify)
if(res){
NSLog("Sent: " + String(data: notification.valueToNotify, encoding: .utf8)!) // This is always printed in the right order
notificationSent()
self.notBuffer.remove(at: self.notBuffer.index(of: notification)!)
}
}
self.notificationLock.signal()
}
}
@objc public func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
processNotificationBuffer()
}