I work on an app that operates a HW device that acts as a BLE peripheral. Our BLE code stack has not changed much since 2017 and has been working very well over the years. We recently started seeing a lot of customer complaints and bad App Store reviews that the device was not working.
I have been investigating this for several weeks now and I'm struggling to narrow down the cause, but it seems to be a change in iOS. With the same app and device FW the issue is almost exclusively seen on iOS 17.x even though ~40% of our user base is still on iOS 16.x.
From my investigation what I see is the CBPeripheral
getting stuck in connecting
state. When it is in this state advertisements are seen in our app, and other apps are able to connect to the device (nRF Connect for example). If I cancel the connection the CBPeripheral
then gets stuck in the disconnecting
state. I can only toggle between these two states and it will remain like this for days.
I have found that initializing a new CBCentralManger
will sometimes "fix" the issue. However, about 50% of the time the new CBCentralManager
comes up in the unknown
state so CoreBluetooth
as a whole seems to be in a weird state.
More effective is killing the app and relaunching. But even then sometimes the CBPeripheral
immediately gets stuck again and it takes multiple killing/launching the app to get back in a working state.
Few points that seem relevant:
- App has central and peripheral background modes enabled.
- App uses state restoration, though most of the times I see this issue there was not a state restore that happened.
- To reproduce the issue the app needs to be in the background for some amount of time, and it happens on foregrounding.
- We will in some cases scan/connect in the background, but I have reproduced this issue without that.
Is anyone else seeing this issue or have ideas what might be causing it?