2016-06-23 12 views
0

Ich verwende CoreBluetooth in Swift 3, um eine serielle Schnittstelle mit BTLE zu simulieren. Der Dienst ist für die zentralen Geräte sichtbar, und alle peripheren (schnellen) Updates der Updates werden ohne Probleme auf der zentralen Seite aktualisiert.Delegierte Methoden werden nicht aufgerufen? (CoreBluetooth)

Wenn ich eine Lese- oder Schreibanforderung von der zentralen Seite senden, sollte eine der peripheralManager() - Delegate-Methoden das Ereignis behandeln; Aber egal, was passiert, keiner der Delegierten Methoden jemals aufgerufen werden und das zentrale Gerät verliert schließlich seine Verbindung (wegen Timeout, glaube ich).

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

Es ist seltsam, dass dieser Code arbeitet und Verbindungen empfangen, da Sie warten müssen, bis Sie einen eingeschalteten Zustand in 'peripheralManagerDidUpdateState' bekommen bevor Sie Dienste bewerben können. – Paulw11

+0

Auch Ihr Empfangscode sieht falsch aus; Sie sollten die empfangenen Daten nicht im 'rx'-Merkmal speichern. Stattdessen sollten Sie es zu einem Puffer hinzufügen, den Ihre App lesen wird (und vorzugsweise eine Benachrichtigung posten oder einen Rückruf aufrufen, um Ihren Code zu benachrichtigen, dass Daten verfügbar sind). – Paulw11

+0

Ich plante, rx als Puffer zu verwenden, den Sie beschreiben. Würde das nicht funktionieren? Auch die Methode periphererManagerDidUpdateState wird nie aufgerufen, ich hatte einen Schalterkasten, der nur beim Einschalten mit der Werbung anfing, aber nie aufgerufen wurde: P –

Antwort

0

Ich hatte ein ähnliches Problem, das mich für Stunden ratlos hatte. Mein Problem war Eigenschaften. Sobald ich hinzugefügt wurde die .lesen Eigenschaft, die didReceiveRead Rückruf genannt:

myCharacteristic = CBMutableCharacteristic(
    type: myUUID, 
    properties: [CBCharacteristicProperties.notify, CBCharacteristicProperties.read], //*** Need Read Permission to READ!! 
    value: nil, 
    permissions: CBAttributePermissions.readEncryptionRequired 
) 
Verwandte Themen