Swift 3 Core Bluetooth not discovering services

Viewed 1311

I'm trying to discover services from a BLE device I've connected to from my iOS app, but when my didDiscoverServices function gets called, the peripheral services array is empty.

The app connects to the device, runs peripheral.discoverServices(nil) and then the didDiscoverServices function gets called, but there are no services returned.

I've read a number of bluetooth related answers and other examples online and as best I can tell, my code is no different to what it should be, except it is not working. I feel like I must've missed something somewhere but I'm not sure what.

I've added my console log below for what I get when running the code, and the bluetooth code at the bottom for reference.

Bluetooth initialised
BLE is powered on
Optional("Nordic_Blinky") found at -72
Scanning stopped
Connect request sent
Connected to <CBPeripheral: 0x1c0301a70, identifier = 0887CF7F-98C8-3FCF-2D10-873FFFFB2B65, name = Nordic_Blinky, state = connected>
Discovering services
Services -- Optional([]) and Error -- nil

My BluetoothHandler class code is below

class BluetoothHandler : NSObject, CBCentralManagerDelegate, CBPeripheralDelegate {

// MARK: Properties
var manager: CBCentralManager!
var targetPeripheral: CBPeripheral!


// MARK: Shared Instance
static let sharedInstance = BluetoothHandler()
private override init() {
    super.init()
    self.startManager()
    print("Bluetooth initialised")
}

// MARK: Functions

func startManager() {
    manager = CBCentralManager(delegate: self, queue: nil)
}

func centralManagerDidUpdateState(_ central: CBCentralManager) {

    var consoleMessage = ""
    switch (central.state) {

    case.poweredOn:
        consoleMessage = "BLE is powered on"
        manager.scanForPeripherals(withServices: nil, options: nil)

    case.poweredOff:
        consoleMessage = "BLE is powered off"

    case.resetting:
        consoleMessage = "BLE Resetting"

    case.unknown:
        consoleMessage = "BLE state unknown"

    case.unsupported:
        consoleMessage = "Device not supported by BLE"

    case.unauthorized:
        consoleMessage = "BLE not authorised"
    }
    print("\(consoleMessage)")

}

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {

    if (peripheral.name == "Nordic_Blinky") {

        print("\(String(describing: peripheral.name)) found at \(RSSI)")
        self.stopScan()

        if targetPeripheral != peripheral {

            targetPeripheral = peripheral
            targetPeripheral!.delegate = self

            manager.connect(targetPeripheral, options: nil)
            print("Connect request sent")
        }

    }

    else if (peripheral.name != nil) {
        print("\(String(describing: peripheral.name))")
    }
}

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
    print("Connected to \(peripheral)")
    peripheral.delegate = self
    peripheral.discoverServices(nil)
    print("Discovering services")
}

func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Any) {
    print("Connection failed", error)
}

func centralManager(_ central: CBCentralManager, didDisconnect peripheral: CBPeripheral) {

    if self.targetPeripheral != nil {
        self.targetPeripheral!.delegate = nil
        self.targetPeripheral = nil
    }
    print("Connection disconnected")
    self.startManager()
}

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
    print("Services -- \(peripheral.services) and Error -- \(error)")

    if let services = peripheral.services {
        for service in services {
            peripheral.discoverCharacteristics(nil, for: service)
        }
    }
}
1 Answers

Try this: swift 3

If your peripheral(BLE device) have services then print in log.

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {

    if let services = peripheral.services as [CBService]!{

        for service in services{

            peripheral.discoverCharacteristics(nil, for: service)
        }
    }
    print("==>",peripheral.services!)
}

func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {

    for newChar: CBCharacteristic in service.characteristics!{

        print(newChar)
    }
}
Related