Scan for peripherals with services returns nothing
I'm trying to scan for a specific device by it's service uuid - in this case JBL speaker, in future cases, I would like to scan for devices inside a car.
At first, I scanned for nearby peripherals with nil
.
self.centralManager?.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey:true])
Once I found my speaker (this is the data I get):
peripheral identifier = 0BD95D98-D979-67DA-F3AA-C6C03781E70B
discovered peripheral = <CBPeripheral: 0x283ed4000, identifier = 0BD95D98-D979-67DA-F3AA-C6C03781E70B, name = JBL Flip 4, state = disconnected>
advertisement data = ["kCBAdvDataRxSecondaryPHY": 0, "kCBAdvDataTimestamp": 643124133.584141, "kCBAdvDataIsConnectable": 1, "kCBAdvDataManufacturerData": <5700d11e 0100ff58>, "kCBAdvDataRxPrimaryPHY": 0, "kCBAdvDataLocalName": JBL Flip 4]
kCBAdvDataManufacturerData = {length = 8, bytes = 0x5700d11e0100ff58}
I connected to the speaker, and when I got the didConnect
callback I called for discover services:
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
self.connectedPeripheral = peripheral
peripheral.delegate = self
peripheral.discoverServices(nil)
}
When didDiscoverServices
services returned I saw the following output:
services = Optional([<CBService: 0x281adc700, isPrimary = YES, UUID = 65786365-6C70-6F69-6E74-2E636F6D0000>, <CBService: 0x281adcb40, isPrimary = YES, UUID = FE8F>])
At this point, I wanted to use the service uuids that I got, and to scan for the JBL speaker.
So instead of called for scanForPeripherals
with nil
, I used an array with the services like this:
self.centralManager?.scanForPeripherals(withServices: [CBUUID(string: "FE8F"), CBUUID(string: "65786365-6C70-6F69-6E74-2E636F6D0000")], options: [CBCentralManagerScanOptionAllowDuplicatesKey:true])
Then I relaunched the app, but this time I didn't find any device. Why is this so?
See the doc of scanForPeripherals(withServices:options:)
:
You can provide an array of CBUUID objects — representing service UUIDs — in the serviceUUIDs parameter. When you do, the central manager returns only peripherals that advertise the services you specify
The service you got 65786365-6C70-6F69-6E74-2E636F6D0000
, you got it AFTER you made before a connection to it (didConnect
), and after "scanning more infos on the device" (discoverServices
).
But it was not advertising it, it was not telling everyone that it has a service with that UUID. It keeps it secret. So you can't scan for it.