Losing advertising packets when CBCentralManager scanForPeripheralsWithServices is left on

Right now, I am scanning for specific BLE peripherals with my iPad app, using this:

[self.cbCentralManager scanForPeripheralsWithServices:serviceUUIDsToScanFor options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@YES}];

I have the "CBCentralManagerScanOptionAllowDuplicatesKey" set true because I need to be able to detect when a peripheral is no longer advertising, so I capture each "didDiscoverPeripheral" callback and set a 3-second timer that notifies the user that that peripheral is no longer in range if another didDiscoverPeripheral hasn't been received in that time. The peripherals all advertise at 100ms intervals.

What's weird is that if I leave the scan on for a long time, the advertising packets slow down, and eventually one of those timers times out, around about one or two minutes for the first instance, and then every 10-20 seconds after that. I've checked with ATS for all the BLE traffic, and there are indeed > 3-second gaps in the advertising packets that the iPad sees, so it's not my code introducing the gap.

Is there some reason long-running scans should not be done on iPadOS (both 18 and 26.1 used)? I've tested out switching my scan to "stopScan" and restart it every 10 seconds, and that seems to have resolved the issue, but it's unclear why that would matter (and that does not seem like an appropriate use of the stop and start scans). Thanks!

Answered by Engineer in 877276022

Even if your app is always in the foreground, the scanning will slow down with time.

Your stopping/starting the scan every 10 seconds to work around this behavior would be considered abuse. While it is in the end up to you, it is an unsupported workaround, and you may encounter unexpected behaviors.

Scanning on behalf of apps is only done at full speed (scanning interval and window) for apps when they are active in the foreground. If the app loses focus or the screen dims, the scan will slow down, and when the screen is off, or the app is no longer on the screen, you will stop getting duplicate advertisements altogether.

Are you seeing this slowdown in one one of the above situations, or while the app is in the foreground and being actively used? Is it the only app in the foreground, or are you using split screen?

Accepted Answer

Even if your app is always in the foreground, the scanning will slow down with time.

Your stopping/starting the scan every 10 seconds to work around this behavior would be considered abuse. While it is in the end up to you, it is an unsupported workaround, and you may encounter unexpected behaviors.

The only place where this is documented is in the Accessory Design Guidelines for Apple Devices

In section 55.5: Advertising Interval, it defines the optimal advertising intervals the accessories should advertise at which would cover the different scanning levels an app would go into.

Unless you are trying to connect to one specific device that does not vary its advertising interval, and you happen to know how fast it is advertising (which is possible to detect with a sniffer), trial and error would not help either, as the connection time would be different for every accessory depending on their advertising parameters.

Also, as undocumented values, our scanning parameters can also change without notice.

Depending on how fast the accessory is advertising, the time to discovery in the worst case scanning state can vary from 30 seconds to many minutes.

If you are able to determine the advertising interval for the accessory you are working with, I might be able to tell you the worst case scenario. If you would like to discuss numbers, please open a support request at https://developer.apple.com/contact/request/code-level-support/ and reference this forum thread in the "Did someone from Apple ask you to submit ..." section


Argun Tekant /  WWDR Engineering / Core Technologies

Losing advertising packets when CBCentralManager scanForPeripheralsWithServices is left on
 
 
Q