I'm using the scanForPeripherals method to retrieve UUIDs from devices near me.
I am able to list UUIDs, however, they are not similar with the UUIDs discovered using nRF Connect application. I tried various testing scenarios, in which I've configure a specific UUID for a peripheral (in another app, installed on a different phone) and tried to discover it using my code, but this too proved unsuccessful (yes, the nRF Connect managed to see the right UUID).
Please see this simplified version of the code:
class ViewController: UIViewController {
var centralManager : CBCentralManager!
var peripherals : [CBPeripheral] = []
override func viewDidLoad() {
super.viewDidLoad()
//Initialise CoreBluetooth Central Manager
centralManager = CBCentralManager(delegate: self, queue: DispatchQueue.main)
}
}
extension ViewController: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if (central.state == .poweredOn){
self.centralManager?.scanForPeripherals(withServices: nil, options: nil)
}
else {
// do something like alert the user that ble is not on
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
peripherals.append(peripheral)
print(peripheral.identifier.uuidString)
}
}
I would like to know why the UUID's appear to be different, and what can I do to discover the same UUIDs as nRF Connect.
BLE devices generally do not have a UUID themselves. The CBPeripheral.identifier
is an internal identifier created by the OS just for internal usage. The UUID you're looking for is a Service UUID, which may be available through the advertising packet, or may only be available by discovery. (There should never be a UUID in the advertising packet that isn't available through discovery, but I did run into a device with buggy firmware just last week where this happened, so it's possible.)
If the Service UUID is being advertised, then you can limit your scan to just devices that include that UUID by passing it to scanForPeripherals
. This is the preferred way to scan. You can fetch the list of advertised services from the advertisementData
dictionary using the CBAdvertisementDataServiceUUIDsKey key.
If the service is not advertised, then you'll need to call discoverServices
. When didDiscoverServices
is called back, you'll find the list of services in the peripheral.services
property.