iOS omits manufacturer data from advertisement in background mode

1.3k Views Asked by At

I work on iOS application which is using BLE for communication with our custom made BLE unit. We want to send specific commands via BLE to the unit automatically.

When user is near unit and specific criteria are met, the app should connect to the unit, "login" the user, send command via BLE and disconnect right away.

These specific criteria are based on manufacturer data from advertisement (i.e. the unit is in "available to login" state when manufacturer data has last byte 0x01, when it's "NOT available to login", last byte is 0x00).

In foreground, this mechanism works flawlessly. We want to do this even when app is in background or terminated (swipe up in dashboard on iPhone).

The mechanism we have implemented:

  • the unit has capability of acting as iBeacon
  • when unit is NOT available for login, the iBeacon is OFF
  • when it IS available for login, the iBeacon will turn ON and wakes up application, upon that the BLE scan will start in background mode
  • background mode setting is bluetooth-central

Problem here is that no matter what I tried, the advertisement:

  1. sometimes it's not discovered at all (looks like it's timing issue?)
  2. when it's discovered, it does NOT contain manufacturer data

Did anyone come across something similar? Any help is appreciated and have a nice day!

1

There are 1 best solutions below

6
On BEST ANSWER

An app simply cannot read raw BLE manufacturer advertisement data when in the background on iOS -- the operating system prohibits it.

Two exceptions to this rule:

  1. iBeacon, which itself is implemented as a specific type of manufacturer advertisement. An app can detect iBeacons in the background on iOS, although only four bytes of readable data (encoded in the major and minor fields) are fully usable. If you can modify your device to send information this way, it will do what you want. However you must use CoreLocation APIs to detect iBeacon, as CoreBluetooth does not allow reading manufacturer data from iBeacon advertisements. If you do use CoreLocation, you cannot use the detections to establish a Bluetooth connection with CoreBluetooth as the two APIs are sandboxed.

  2. Overflow Area advertisements. Backgrounded iOS apps can read these special types of manufacturer advertisements when in the background but only if the screen is turned on. (It is often possible to force the screen on at specific times by sending a local notification.) See my blog post here for more info: http://www.davidgyoungtech.com/2020/05/07/hacking-the-overflow-area

An alternative to detecting manufacturer advertisements is to use BLE Service advertisements with attached data. For this to work, you'd need to define a 16 bit or 128 bit GATT Service UUID and send out an advert with attached data bytes. Eddystone beacon formats work this way, and allow detection in the background on iOS. This is probably the best approach if you can alter the BLE hardware.