1

I am using this iBeacon BLE device https://www.beaconzone.co.uk/LC01BodyTemperature and trying to read its temperature data.

I've successfully managed to do it in Android Kotlin using RxAndroidBle by accessing ScanResult.scanRecord.bytes and now I'm trying to do the same thing in iOS Swift using RxBluetoothKit by reading ScannedPeripheral.advertisementData.manufacturerData.

From my understanding of documentation that field should be the Android equivalent of the bytes field but in every test I did it always returned nil. I've also tried to access it natively in the centralManager(_:didDiscover:advertisementData:rssi:) function by accessing CBAdvertisementDataManufacturerDataKey in advertisementData but that also returned nil.

The bytes I need to get from the iBeacon's raw data are in position 45 (integer part of temperature) and 46 (fractional part of temperature) but I don't get any byte array whatsoever transmitted in the advertisementData of centralManager(_:didDiscover:advertisementData:rssi:) that has the length suggested by the manual of the device.

Do you have any suggestions on what I'm doing wrong?

  • What's your scan option with the `CBCentralManager`? Your device might appear multiples times in `centralManager(_:didDiscover:advertisementData:rssi:)`, the thing, is that's it's might appear piece by piece, sometimes without the name, then with the name, etc. ie, check until the advertisementData be there? – Larme Dec 11 '20 at 09:31
  • @Larme I use this options `let options = [ CBCentralManagerOptionRestoreIdentifierKey: "RestoreIdentifierKey", CBCentralManagerScanOptionAllowDuplicatesKey: true ] as [String: AnyObject]` and yes it appears piece by piece but the information I'm looking for it's not present. –  Dec 11 '20 at 09:48
  • If you use LightBlue.app, does the advertisement appear there? – Larme Dec 11 '20 at 09:56
  • @Larme it only shows the Service Data, which does not contain the information I need, it doesn't show the manufacturer data... –  Dec 11 '20 at 10:14
  • If you post the bytes that Android reads from the advertisement (or the spec of the temp wristband’s advert which is password protected) I can show you how to read this on iOS using CoreLocation APIs. – davidgyoung Dec 11 '20 at 12:58

1 Answers1

3

You cannot access iBeacon advertisement data using CoreBluetooth (which is what RxBluetoothKit uses under the hood).

iOS uses CoreLocation API for interfacing with iBeacons.

If you want to use iBeacons and advertise some data you have two options:

  1. You can encode the temperature data into either major or minor of the iBeacon advertisement and use CoreLocation API
  2. You can advertise Service Data Type in your advertisement — then you can use CoreBluetooth to access that data (because iBeacon advertisement is stripped by iOS in CoreBluetooth). From Bluetooth website:
data type value data type name reference for definition
0x16 «Service Data» Bluetooth Core Specification:Vol. 3, Part C, sections 11.1.10 and 18.10 (v4.0)
0x20 «Service Data - 32-bit UUID» Core Specification Supplement, Part A, section 1.11
0x21 «Service Data - 128-bit UUID» Core Specification Supplement, Part A, section 1.11
Dariusz Seweryn
  • 3,212
  • 2
  • 14
  • 21
  • Doesn't the CoreLocation API just tell me the proximity to the sensor? I can't find the methods that would transmit the data I'm searching for in the documentation. Could you please point me to it? –  Dec 11 '20 at 11:28
  • I have edited the answer. You cannot get additional data from `CoreLocation` but you can encode data in it. Or you can use a different advertisement data. – Dariusz Seweryn Dec 11 '20 at 11:41