Search code examples
iosbluetooth-lowenergycore-bluetoothcbperipheral

CBPeripheralManager: Does add(_ service: CBMutableService) advertise peripheral?


SCENARIO

I am working on a framework that must leverage the CoreBluetooth framework in order to send data over BLE. I have already finished my requirement to communicate environmental data using iBeacons, but I need to send data now from one device to another. I will be using the CBCentralManager from one application to scanForPeripherals and another application that will be broadcasting a peripheral with a CBUUID and then the central application will request data from the service's characteristics.

I have all of this working properly from what I can tell: a. I can scan for peripherals in my area and get a lot of results around the building, but not the peripheral that I broadcast from my device. b. I can add the service that contains my CBUUID from the CBPeripheralManager and get a success in the didAddService delegate method.

But my CBPeripheralManager still can not discover my peripheral.

CODE

// To scan...
centralManager?.scanForPeripherals(withServices: nil, options: nil)

// To broadcast...
let dataString = "SomeValueFromData"
let data = dataString.data(using: .utf8)
let base64 = data?.base64EncodedData()

let uuid = CBUUID(nsuuid: Constants.Scan.uuid)
let service = CBMutableService(type: uuid, primary: true)
let properties = CBCharacteristicProperties.read
let characteristic = CBMutableCharacteristic(type: uuid, properties: properties, value: base64, permissions: .readable)
service.characteristics = [characteristic]
peripheralManager.add(service)

Note: For both CBCentralManager and CBPeripheralManager I am instantiating my managers and then waiting for the didUpdateState delegate methods to get called and only begin scanning or broadcasting if the state is poweredOn.

HYPOTHESIS

I think that I have my CBCentralManager set up correctly to scan for all peripherals (not specifying any service UUIDs), and I still can not discover my peripheral. I think there is a flaw in the 'broadcast' code. I have done some research on the add(_ service: CBMutableService) function on CBPeripheralManager and I am not sure if I am understanding this correctly.

QUESTION

a. Does the add(_ service: CBMutableService) begin the 'broadcast' of a CBPeripheral? I am under the impression that this is the only method I have to call and this will 'add' the service to some sort of queue that will be sent out on BLE to be discovered.

From the Apple Documentation on the add(_:) method, "Publishes a service and any of its associated characteristics and characteristic descriptors to the local GATT database."

I have done a good amount of research about the local GATT database and Apple does not provide much information.

b. Does the local GATT database operate in the manner as the queue like I described above and will begin the 'broadcast' of my peripheral automatically? Or is there more I have to do?


Solution

  • No, add(_ service:) only adds the service to the CBPeripheralManager. To actually advertise services you need to call startAdvertising(_ advertisementData:).

    advertisementData is a dictionary. You specify an array of UUIDs that you want to advertise for the key CBAdvertisementDataServiceUUIDsKey.

    The reason you must do this is that a peripheral may offer more services than it advertises. Since there is limited space in the advertisement packet you generally only advertise your "primary" service; the service that is used to discover your peripheraL. Once it is connected the central can discover the other services provided by your peripheral.