I'm using the CBPeripheralManager to broadcast advertisements on an iPhone 13 running iOS 16.5. I'm trying to include data in the CBAdvertisementDataLocalNameKey but am not seeing the expected behavior.
The following works:
let customData: String = "789"
peripheralManager.startAdvertising([CBAdvertisementDataLocalNameKey: customData])
But the following doesn't work. No errors are seen, but the data just doesn't appear in the advertisement.
let customData: [UInt8] = [1,2,3]
peripheralManager.startAdvertising([CBAdvertisementDataLocalNameKey: customData])
How do I pass an array of bytes to include in the advertisement? Thanks
CBAdvertisementDataLocalNameKey is required to be as string, as documented. For your specific example, I expect the following to "work" (as in "be advertised"):
let customData = String(decoding: [1,2,3], as: UTF8.self)
However, this will only work for byte sequences that are valid UTF8 (and this happens to be). Non-UTF8 byte sequences are invalid in this field. This is not an iOS restriction; it's a Bluetooth requirement. In the CSS v11, section 1.2, the local name field is defined:
The Local Name data type shall be the same as, or a shortened version of, the local name assigned to the device. The Local Name data type value indicates if the name is complete or shortened. [...]
A shortened name shall only contain contiguous characters from the beginning of the full name. For example, if the device name is ‘BT_Device_Name’ then the shortened name could be ‘BT_Device’ or ‘BT_Dev’.
The type is then specified as utf8s
. The "local name assigned to the device" is from the Core Specification, version 5.3, section 6.23:
A UTF-8 encoded User Friendly Descriptive Name for the device with type
utf8{248}
.
You cannot put random bytes here.
Using this field for random strings, even if they are technically "valid" also violates the rules for this field and is frustrating to users who scan for devices. They will show up as gibberish in the list. Please avoid doing this to users.
If you want to put random bytes in the advertising packet, they go in the Manufacturer Data. You can put any bytes you like there. (But see comments below: iOS doesn't allow this. It is very possible that Apple provides no way to advertise arbitrary data, particularly since multiple apps may be trying to do this simultaneously.)
Keep in mind, however, from the docs:
Core Bluetooth advertises data on a “best effort” basis, due to limited space and because there may be multiple apps advertising simultaneously. While in the foreground, your app can use up to 28 bytes of space in the initial advertisement data for any combination of the supported advertising data keys. If no this space remains, there’s an additional 10 bytes of space in the scan response, usable only for the local name (represented by the value of the CBAdvertisementDataLocalNameKey key). Note that these sizes don’t include the 2 bytes of header information required for each new data type.