2
votes

brand new here.

The Tl;dr: Can an iOS device advertise a CB advertisement (CBAdvertisementDataServiceUUIDsKey and/or CBAdvertisementDataLocalNameKey) that can be scanned for by another iOS device?

I believe my question is fresh based on deprecations and changes to CoreBluetooth and CoreLocation in the later versions of iOS. Also, for now, I'm only referring to "foreground" ops.

From what I have read and tested, a peripheral can transmit a Beacon Region (unique Proximity UUID, major and minor (but notably without the "identifier")) using CL. And with CB, a peripheral can also "advertise" either of two small additional amounts of data: CBAdvertisementDataServiceUUIDsKey and CBAdvertisementDataLocalNameKey.

What I've not been able to achieve is having the device (e.g. iPhone) scan using CB for either of these additional keys, nor as I mentioned the optional "identifier" using either CL or CB.

The only option to specify a scan requires a CBUUID, but an undiscovered iOS peripheral cannot technically advertise that:

central.scanForPeripherals(withServices: [CBUUID]?, options: [String : Any]?)

It seems the following would work but it doesn't seem the advertisementData includes the keys above, even as [String : Any]:

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

Any help/answers here would be appreciated. Thanks!

1
You are confusing a couple of things. An app can advertise as an iBeacon and also scan for iBeacons; this is Core Location functionality. An app can advertise a GATT service using Core Bluetooth and also scan for BLE gatt services. It is more efficient if you know the UUID of the service that is being advertised but you can also specify nil as the scan parameter to discover all peripherals. None of this has changed for at least 3 versions of iosPaulw11
After you initiate scanning you will get a call to the delegate method you have shown for each peripheral that matches your scan.Paulw11

1 Answers

5
votes

Unfortunately iOS is pretty unhelpful here. Apple locks down CoreBluetooth in a number of ways.

There are three basic ways of sending/receiving advertisements:

iBeacon

  • You can scan for iBeacon advertisements using CoreLocation in the foreground and background, with quick responses, but data fields are limited to ProximityUUID, major and minor.

  • You can transmit iBeacon advertisements using CoreBluetooth in the foreground only.

Bluetooth LE Service Advertisements

  • You can transmit these in the foreground (but not the background) using CoreBluetooth, but you cannot attach arbitrary data. You can, however, send an arbitrary service UUID of 16 bytes.

  • You can scan for service advertisements with CoreBluetooth in the foreground and background and read the service UUID with quick foreground responses and slow background responses. You can also read attached data from these advertisements up to 18 bytes if using a 16 bit service UUID. Eddystone works this way.

Bluetooth LE Manufacturer Advertisements

  • You cannot advertise manufacturer advertisements at all using CoreBluetooth on iOS, except for the special iBeacon advertisement as described above.

  • You can scan for manufacturer advertisements using CoreBluetooth and you can read attached data, up to 23 bytes. You cannot detect in the background at all, but foreground detections are quick.

Bottom line: if you want to send advertisement data from one iOS device to another in the foreground or background, iBeacon is the only way.