I have a view controller that scans for BLE beacons that are advertising only and do now allow incoming connections. I can see the bytes that I want by inspecting the service data section (CBAdvertisementDataServiceDataKey
) of the advertisement, but I can't actually access the raw bytes of the data as variable.
Here is the CM callback:
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
var advBytes: String!
if let dictionary = advertisementData[CBAdvertisementDataServiceDataKey] as? [String: Any] {
if let gatt = dictionary["Generic Attribute Profile"] as? [String: String] {
advBytes = gatt["bytes"]?[2...]
} else {
print("Can't convert byte array to string")
}
}
else {
print("Couldn't decode advertisement \(advertisementData[CBAdvertisementDataServiceDataKey])")
}
When the code is run, the console outputs:
Couldn't decode advertisement Optional({
"Generic Attribute Profile" = {length = 7, bytes = 0x6413000a000000};
})
How can I access this bytes
part of the GATT as a variable?
CodePudding user response:
According to the doc of CBAdvertisementDataServiceDataKey
, the value is [CBUUID: Data]
.
So it should be:
if let dictionary = advertisementData[CBAdvertisementDataServiceDataKey] as? [CBUUID: Data] {
}
Now, if I remember correctly, the Service ID you are looking for GATT, is 1801
. It's just that Apple translate it automatically into a human readable "Generic Attribute Profile". You can test it with this:
let service = CBUUID(string: "1801")
print("Service UUID: \(service.uuidString) - \(service)")
They must have override description of CBUUID
to print "words" when it's a known UUID.
Now, you could do this:
let genericAttributeProfileData = dictionary[CBUUID(string: "1801")]
let subData = genericAttributeProfileData[0...0]
// etc.