Я использую CoreBluetooth в Swift 3 для имитации последовательного порта с BTLE. Эта услуга видна центральным устройствам, и любые обновления периферийной (быстрой) стороны обновляются без проблем.Методы делегатов не вызываются? (CoreBluetooth)
Когда я отправляю запрос на чтение или запись с центральной стороны, один из методов-делегатов периферийного диспетчера() должен обрабатывать событие; однако независимо от того, что происходит, ни один из методов делегата никогда не вызван, и центральное устройство в конечном итоге теряет связь (из-за таймаута, я считаю).
class BTConnectionHandler: NSObject, CBPeripheralManagerDelegate {
var cbManager: CBPeripheralManager!
var serialService: CBMutableService!
var tx: CBMutableCharacteristic!
var rx: CBMutableCharacteristic!
override init() {
super.init()
cbManager = CBPeripheralManager(delegate: self, queue: nil)
cbManager.startAdvertising(ADVERTISEMENT_DATA)
serialService = CBMutableService(type: SERIAL_UUID, primary: true)
tx = CBMutableCharacteristic(type: TX_UUID, properties: TX_PROPERTIES, value: nil, permissions: TX_PERMISSIONS)
rx = CBMutableCharacteristic(type: RX_UUID, properties: RX_PROPERTIES, value: nil, permissions: RX_PERMISSIONS)
serialService.characteristics = [tx,rx]
cbManager.add(serialService)
}
// PERIPHERAL (this) Write to TX
internal func write(string: String) -> Bool {
let data = string.data(using: String.Encoding.utf8)!
tx.value = data
return cbManager.updateValue(data,for: tx,onSubscribedCentrals: nil)
}
// PERIPHERAL (this) Read from RX
internal func read() -> String? {
if let outString = String(data: rx.value!, encoding: String.Encoding.utf8) {
return outString
} else {
print("RX buffer is empty")
return nil
}
}
// CENTRAL read from TX
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) {
print("Read request received from central device")
request.value = tx.value
cbManager.respond(to: request, withResult: .success)
}
// CENTRAL write to RX
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {
print("Write request(s) received from central device")
for request in requests {
rx.value = request.value
cbManager.respond(to: request, withResult: .success)
}
}
// Print state of peripheral manager as it changes
func peripheralManagerDidUpdateState(_ peripheral:CBPeripheralManager) {
print(peripheral.state)
}
}
Странно, что этот код работает и получение соединений, так как вы должны ждать, пока вы не получите приведенный в действие на состояние в 'peripheralManagerDidUpdateState' прежде чем вы сможете рекламировать любые услуги. – Paulw11
Кроме того, ваш код получения выглядит неправильно; вы не должны хранить полученные данные в характеристике 'rx'. Скорее, вы должны добавить его в некоторый буфер, который ваше приложение будет читать (желательно отправить уведомление или вызвать обратный вызов, чтобы уведомить ваш код, что данные доступны) – Paulw11
Я планировал использовать rx в качестве того буфера, который вы описываете, это не сработает? Также не вызван метод peripheralManagerDidUpdateState, у меня был случай переключения, чтобы начать рекламу только при включении, но он никогда не вызывался: P –