Discover and connect to BLE peripherals more rapidly in background

We are developing an app which connects to a BLE peripheral in the background whenever it gets close to it. What we have used so far is that we monitor a circular region. When the phone enters the region the app will start scanning for peripherals and when it discovers the peripheral it connects to it.

This worked pretty well for the last few iOS versions, perhaps iOS 14-16. It wasn't perfect but for the most part it would feel like it connected rather quickly when you would approach the BLE peripheral. If you listen to music via BLE or talk to someone using your BLE headset then it could sometimes work noticeably worse. But, as said, for the most part it would work satisfactory.

Starting with iOS 17 and analyzing the functionality over the past 6 months or so we've noticed a clear worsening of it. It does generally connect to the peripheral but the user might often have to wait for quite some time. Rather frequently the user must even light up the screen of the phone before anything even happens. It appears that some sort of resource allocation, battery saving feature or similar has affected this functionality greatly. The time difference between entering a region and physically approaching the device is generally around 2-3 minutes.

We have tried to do it more in line with documentation and follow the guidelines that we find in:

https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html

So in doing this we do not start scanning for peripherals when a region is entered, but instead we directly invoke connectPeripheral:options:. This way we offload to the system that we want to connect to that peripheral. However, when testing this we see no real improvement. Sometimes it connects satisfactorily. Sometimes it doesn't really connect at all. Many times it connects if the user lights up the screen. So just looking at what the user is experiencing our analysis is that doing it this way works even worse than what we previously did.

I understand that the system has many resources to consider and that some may have to wait while others perform things. But are there any documentation on what one could expect from initiating a connectPeripheral:options: from the background? In the link I posted it simply states the iOS device will reconnect when the user returns home. So not much detail in terms of performance which is crucial for our application.

If there aren't any further details on the performance, are there any other ways to improve this functionality? We are not looking at draining the battery whatsoever but we simply need our background running app to be as responsive as possible for a few minutes after it has been launched by the region monitoring. We understand that battery life is important but since this happens rarely and sparsely (not more than a few times per day) it seems reasonable that there should be a way to be able to make it function properly.

There isn't anything you can do to effect the time to discovery and connection on the app side. If a faster discovery is required, the only solution in your hands is to have the BLE accessory advertise faster.

To have a high probability of being discovered by an iOS device you should use the recommended advertising interval of 20 ms. If accessory power savings is a concern, you can switch to using one of the following longer intervals for increased chances of discovery: 152.5 ms, 211.25 ms, 318.75 ms, 417.5 ms, 546.25 ms, 760 ms, 852.5 ms, 1022.5 ms, 1285 ms

While these will perform better than a randomly picked interval in the same neighborhood, they are not magic, and the longer the interval the longer it will take to discover.

Thanks for the reply! I don't consider this a BLE/radio issue but simply a resource management issue on the iPhone. We have attempted to use 20ms advertising interval with no noticable improvement. The user can still stand there waiting for 20-30 seconds and then when they light up the screen on the phone it suddently connects. So it appears that the phone simple does not do any scanning during some times when background apps have requested it (or connect for that matter).

Seeing as this is a shortlived process (a few minutes maximum few times per day) it seems as though this could work flawlessly without much battery impact. What I am curious about is what has changed over the past iOS versions making the funcionality work so much worse. I don't see any documentation regarding this and I'm curious if anyone knows more than I do.

Discover and connect to BLE peripherals more rapidly in background
 
 
Q