Peripheral name is nil when scanning with CoreBluetooth on macOS

Viewed 497

When I run the below code within my macOS application - many peripherals have no name - yet when I open "Bluetooth Preferences" on the same computer I can see their names.

What steps am I missing when scanning for bluetooth devices to get their names?

import Foundation
import CoreBluetooth

class Scanner: NSObject, CBPeripheralDelegate, CBCentralManagerDelegate {
    var centralManager: CBCentralManager?

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        switch (central.state) {
           case .poweredOn:
            print("BLE Powered On - scanning")
            centralManager?.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
            break
        default:
            print("Unknown Case")
        }
    }

    internal func centralManager(_ central: CBCentralManager,
        didDiscover peripheral: CBPeripheral,
        advertisementData: [String : Any],
        rssi RSSI: NSNumber)
    {
        print("discovered: \(peripheral.name ?? "nil")")
    }

    func start() {
        print("starting central manager")
        centralManager = CBCentralManager(delegate: self, queue: nil)
    }
}
1 Answers

Peripheral can use two names one for advertisement and one in GAP, try use both (or any present) as below:

internal func centralManager(_ central: CBCentralManager,
    didDiscover peripheral: CBPeripheral,
    advertisementData: [String : Any],
    rssi RSSI: NSNumber)
{
    print("advertised: \(advertisementData[CBAdvertisementDataLocalNameKey] as? String ?? "nil")")
    print("GAP name: \(peripheral.name ?? "nil")")
}

also you can use CBPeripheralDelegate to observe name update by callback

    @available(iOS 6.0, *)
    optional func peripheralDidUpdateName(_ peripheral: CBPeripheral)

some devices might report it in delay.

Related