I have found something really interesting.
I was struggling in this exact issue for days until I've found a reasonable "almost 100%" solution.
I have a central (the app) that scans for a specific device with a specific service all the time, 24/7 (my device is a pedometer)
whenever my device has interesting data to send (let's say it has aggregated a few steps) it advertises and pass the data whenever a connection is established.
As you mentioned, when the app is in the foreground, everything is perfect.
When the app is in the background there are 3 scenarios:
- App in the background, phone is unlocked - Works perfect
- App in background, phone is locked, screen is lighted - Works perfect
- App in background, phone locked, screen is off - Doesn't work!
Now, Let's focus on the 3rd scenario:
If my app is running in a background and the phone is locked and the screen is off when my device is advertising - the central will not find it nor connect it.
whenever I cause the screen to light up (by clicking the home button or the lock button at the iPhone top) - Voilla! - within 1 to 5 seconds I get the central to connect to the device.
Now the plot thickens:
By working on the app and running it for several days, I found that this behaviour is not consistent.
Sometimes my phone was away from my device for a few hours, then, whenever I got close to the device, my app discovered it (without me touching anything, my phone was locked, and screen is off).
then I figured out that Apple has a timeout for re-discovering a device when the app in the background and phone is locked (with screen off).
But this made me try something totally different:
After passing the data from the device to the phone, I killed the connection completely, then after a minute of disconnection, I started advertising again.
In this case, the phone, in almost 100% of the times manages to find and connect to the device even if it's locked with screen off.
2 things to know about this solution:
- It takes the phone between 10 seconds to 5 minutes to make the connection.
- The connection HAS to be killed by the device itself (because the disconnection function of the iOS BLE stack is not a real low level disconnection)
Depending on what your peripheral does and the nature of the connection,
this solution may suit you.
Please let me know what do you think.