Can a non-iOS central discover an iOS peripheral advertising in the background / terminated state?

I'm building an access-control feature. My iOS app acts as a BLE peripheral, and a fixed door reader acts as the central. The app produces an encrypted token; the reader receives that token, validates it, and unlocks the door. The reader is a custom, non-iOS BLE device (embedded module), not an Apple device.

I need this to keep working while the app is in the background, and ideally after it has been terminated. I've enabled the bluetooth-peripheral background mode (UIBackgroundModes).

What I understand so far (please correct me)

From the startAdvertising(_:) documentation and prior forum threads, when a CBPeripheralManager advertises while the app is in the background:

  • CBAdvertisementDataLocalNameKey is not advertised, and
  • the advertised service UUIDs are moved to a special "overflow" area that "can be discovered only by an iOS device that is explicitly scanning for them."

That seems to imply a non-iOS central cannot discover my peripheral by service UUID once the app is backgrounded. This is exactly my concern.

Questions

  1. Background discovery — Given the overflow-area behavior, is there any supported way for a non-iOS central to discover an iOS peripheral that is advertising while the app is backgrounded? Or is discovery by a non-Apple scanner fundamentally blocked in that state?
  2. Advertisement payload — My token could be delivered two ways: (a) embedded directly in the advertisement (e.g. CBAdvertisementDataManufacturerDataKey / service data), or (b) via a GATT characteristic after connection. In the background, is manufacturer data / service data included in the advertisement at all, or is it dropped like the local name?
  3. Characteristic read while backgrounded — If a connection does succeed, can the reader still read or subscribe to a GATT characteristic served by my app while the app is in the background? Any limits on value size or notifications in that state?
  4. Terminated state — With State Preservation and Restoration (CBManagerOptionRestoreIdentifierKey + peripheralManager(_:willRestoreState:)), will the system keep advertising and relaunch my app into the background when the reader connects, even after the app was terminated by the system? Does the same overflow-area limitation apply to restored advertising?
  5. Force-quit — My understanding is that if the user force-quits the app (swipe up in the App Switcher), the system will not relaunch it or preserve its Bluetooth state. Is that correct, and is there any supported exception?
  6. Recommended design — Given the goal (a non-iOS reader must reliably receive an encrypted token from a backgrounded/terminated iOS app), is the peripheral role even the recommended approach? Or should I invert the roles (reader = peripheral, app = central), which seems better suited to background operation?

Thanks in advance.

In general, choosing the app to be a peripheral if expecting to work when it is not active in the foreground would not be my first choice. This is due to the limitations you already mentioned about advertising data, and the fact that advertising is done on a best effort basis, and when in the background, the advertising will slow down, and at times stop altogether, depending on what else needs to be using Bluetooth resources at the time.

So, making the app central is a much better solution. But let me address your specific questions too:

Background discovery — Given the overflow-area behavior, is there any supported way for a non-iOS central to discover an iOS peripheral that is advertising while the app is backgrounded? Or is discovery by a non-Apple scanner fundamentally blocked in that state?

A non-Apple central unit will be able to see the advertisements, but would not be able to access any of the information in the overflow area, which could be essential in recognizing the device, or even transferring a token like you want to do.

Advertisement payload — My token could be delivered two ways: (a) embedded directly in the advertisement (e.g. CBAdvertisementDataManufacturerDataKey / service data), or (b) via a GATT characteristic after connection. In the background, is manufacturer data / service data included in the advertisement at all, or is it dropped like the local name?

You don't want to rely on advertising to pass that kind of data. Not only it may end up in the overflow area, but even if you were the central and the device peripheral, extensive data bits like that are usually relegated to the secondary advertising packet SCAN_RSP. When the central app is in the background it will be switched to passive scan, and ignore the secondary packet, and use cached information instead - as technically the advertising packets are not meant to be carrying dynamic data like a token would be. While this would work when the central app is in the foreground, it is unlikely to be reliable in the background. So, the reliable solution is to connect and read the data from a characteristic.

Characteristic read while backgrounded — If a connection does succeed, can the reader still read or subscribe to a GATT characteristic served by my app while the app is in the background? Any limits on value size or notifications in that state?

Once you are connected, you can do I/O as usual. there is no documented limitations for that, but keep in mind that a backgrounded app has other systemwide limitations, like ~10 second execution time, probability of being terminated if the system needs memory or other resources, etc. For passing a token it should be OK, but you wouldn't want to send Kb's of data when in the background.

Terminated state — With State Preservation and Restoration (CBManagerOptionRestoreIdentifierKey + peripheralManager(_:willRestoreState:)), will the system keep advertising and relaunch my app into the background when the reader connects, even after the app was terminated by the system? Does the same overflow-area limitation apply to restored advertising?

Limitations apply when the app is not active in the foreground, whatever the mechanism is that put it there.

Force-quit — My understanding is that if the user force-quits the app (swipe up in the App Switcher), the system will not relaunch it or preserve its Bluetooth state. Is that correct, and is there any supported exception?

That is correct. If you use Accessory Setup Kit to discover and connect to your devices, then the app will be relaunched even with a force-quit. there are no other exceptions to that.

Recommended design — Given the goal (a non-iOS reader must reliably receive an encrypted token from a backgrounded/terminated iOS app), is the peripheral role even the recommended approach? Or should I invert the roles (reader = peripheral, app = central), which seems better suited to background operation?

My recommended design would be to switch the roles, use Accessory Setup Kit if you can, and don't overload the advertisements with the token and use a characteristic to read and write as necessary.

References: https://developer.apple.com/documentation/accessorysetupkit/

https://developer.apple.com/documentation/technotes/tn3115-bluetooth-state-restoration-app-relaunch-rules


Argun Tekant /  WWDR Engineering / Core Technologies

Can a non-iOS central discover an iOS peripheral advertising in the background / terminated state?
 
 
Q