Я создал периферийное устройство в своем приложении для iOS, которое имеет характеристику, которую я использую для отправки данных размером около 540 байт.Я не могу получить данные на центральной стороне (не iOS).Как мне реагировать на события подписки и запрашивать чтение из подключенного централизованного центра для успешной передачи данных?
Я испробовал следующие подходы.
1.Подписаться на характеристику и выполнитьблок данных
, когда центральный сервер подписывает (разрешает уведомления) на характеристику, я вызываю
let isSuccessful = peripheralManager.updateValue(data, for: characteristic, onSubscribedCentrals: nil)
Данные имеют размер около 540 байтов.Когда я проверяю возвращаемое значение, оно возвращает true, даже если оно передает только 20 байтов в подписанный центр.
Если он когда-либо возвращал false, что по какой-то причине не так, я делал это
if !isSuccessful {
let range = 0 ..< 19
globalDataVariable?.removeSubrange(range)
}
Я ожидал, что приведенный ниже метод делегата ПериферическийМенеджер будет запущен, но это не так..
func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
guard let data = globalDataVariable else { return }
let isSuccessful = peripheral.updateValue(data, for: characteristic, onSubscribedCentrals: nil)
if !isSuccessful {
print("Data still pending..... ")
let range = 0 ..< 19
shareData?.removeSubrange(range)
}
}
Для порции я сохраняю данные для отправки в свойстве класса, а затем удаляю данные, которые уже отправлены.Центральное значение maximumUpdateValueLength
составляет 20 байтов.Я не уверен, что этот подход к чанки и отправке правильный или я правильно делаю чанкинг.
2.Если для характеристики имеется уведомление, центральное устройство сделает запрос на чтение.
Для этого подхода, когда существует подписка от центрального на указанную характеристику, периферийное устройство будет вызывать
characteristic.value = data // doing this for handling the read request
peripheralManager.updateValue(data, for: characteristic, onSubscribedCentrals: nil)
когда центральный получит уведомление с частичными данными, он отправит запрос на чтение к периферийному устройству.
На периферии я обрабатываю это следующим образом.
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) {
switch(request.characteristic.uuid) {
case characteristicUUID:
print(request.offset)
guard let data = characteristic.value else { return }
guard request.offset < data.count else {
print("Invalid Offset")
peripheralManager.respond(to: request, withResult: .invalidOffset)
return
}
request.value = data.subdata(in: request.offset ..< data.count)
peripheralManager.respond(to: request, withResult: .success)
default:
print("Unknown Characteristic")
}
}
Этот подход работает для другой характеристики, которая у меня есть, но она используется для отправки сравнительно небольшого объема данных, меньше чем500 байтов, но для данных более 512 байт это не так
Я также следовал этой теме Чтение длинных значений характеристик с использованием CoreBluetooth , но подход к разделению на блоки не был описан в нем.
Являются ли эти подходы правильными?Есть ли другой способ обработки чтения / подписки длинных значений признаков?