2016-06-23 5 views
0

Я использую 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) 

} 


} 
+0

Странно, что этот код работает и получение соединений, так как вы должны ждать, пока вы не получите приведенный в действие на состояние в 'peripheralManagerDidUpdateState' прежде чем вы сможете рекламировать любые услуги. – Paulw11

+0

Кроме того, ваш код получения выглядит неправильно; вы не должны хранить полученные данные в характеристике 'rx'. Скорее, вы должны добавить его в некоторый буфер, который ваше приложение будет читать (желательно отправить уведомление или вызвать обратный вызов, чтобы уведомить ваш код, что данные доступны) – Paulw11

+0

Я планировал использовать rx в качестве того буфера, который вы описываете, это не сработает? Также не вызван метод peripheralManagerDidUpdateState, у меня был случай переключения, чтобы начать рекламу только при включении, но он никогда не вызывался: P –

ответ

0

У меня была аналогичная проблема, которая заставляла меня часами качать. Моя проблема была в свойствах. Как только я добавил .read собственность, didReceiveRead обратного вызова называли:

myCharacteristic = CBMutableCharacteristic(
    type: myUUID, 
    properties: [CBCharacteristicProperties.notify, CBCharacteristicProperties.read], //*** Need Read Permission to READ!! 
    value: nil, 
    permissions: CBAttributePermissions.readEncryptionRequired 
) 
Смежные вопросы