iOS Question How do i search and connect to BLE devices in the background? (iOS 16)

ema01

Member
Licensed User
Longtime User
As application developers, I LOVE it when a new version of the OS is released and things break. Don't we all love it?

We have an application that was working fine since the last time they changed how things work.
In fact it worked fine up until iOS 15.8

The application purpose is to scan for certain BLE devices in the background. When a suitable device is found it has to connect to it, exchange some data and stay connected.

We already have the bluetooth-central UIBackgroundModes string added to the plist, the NSBluetoothPeripheralUsageDescription and NSBluetoothAlwaysUsageDescription strings in place and the app store review doesn't complain.

However, after the iOS update the application stops working 10-20 seconds after going into the background, if not already connected to a device, and opening it again restarts the application instead of resume it. In debug mode, the debugger exit
I've started looking in the documentation, but i've yet to find what changed in iOS 16 and how to restore the intended app behaviour
 

JordiCP

Expert
Licensed User
Longtime User
I have an app that does a similar thing, scanning for certain serviceUUIDs in the background in order to perform some actions when they are found.
It hasn't failed up to now, and I haven't yet received any complain about iOS 16 (perhaps it will happen soon)

Remember that it is possible that the OS can kill your app at any moment, regardless of the plist entries. Perhaps iOS 16 is more aggressive. But If the BLE is correctly programmed (and nothing has changed regarding permissions) Corebluetooth should continue scanning in the background, even if your app has been killed (not if the user has killed it) and restart your app when it finds the target service UUID.
 
Upvote 0

ema01

Member
Licensed User
Longtime User
Meanwhile I've started receiving reports for other apps that have issues with BLE.
A quick search for "ios 16 change ble requirements" turned up this

BLE device disconnect after 90s on iOS 16 beta - https://developer.apple.com/forums/thread/713095?answerId=728820022#728820022

So another post on this iOS16 issue. It appears Apple changed the Bluetooth Development guidelines so Minimum and Maximum connection intervals are now Min 15 ms, and Max 30 ms. This is defined in Nordic SDK in app_ble.c you need to change your parameters to this now: /* Minimum acceptable connection interval (20ms). Force the connection interval to be 15ms to maximize throughput. iOS devices will not handle a faster interval. Refer to the Apple Bluetooth development guidelines for further details. / #define MIN_CONN_INTERVAL MSEC_TO_UNITS(15U, UNIT_1_25_MS) / Maximum acceptable connection interval (30ms). */ #define MAX_CONN_INTERVAL MSEC_TO_UNITS(30U, UNIT_1_25_MS)

We use different BLE devices, some have the default connection interval inside the new range, some don't and if this is the case the thousands of devices we have out there will have to be recalled for firmware updates. We never bothered to change these parameters because if they work, you know... You can imagine how i am feeling
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
That's not good news and I hope that this is not the cause :(

For my own interest, have you found the official source where it states that these timing parameters have been changed ?

Anyhow, I'd double-check that this is the real (or only) problem. If what you are describing only happens in background but not in foreground, maybe we are talking about another issue.
 
Upvote 0

Filippo

Expert
Licensed User
Longtime User
Anyhow, I'd double-check that this is the real (or only) problem. If what you are describing only happens in background but not in foreground, maybe we are talking about another issue.
Hi @JordiCP ,

In my app the problem comes already in the foreground.
The connection to the BLE device works without problems, but the connection is terminated after 1 or 2 hours.
Up until iOS 15.8 it never had any problems.
The question now is: can we fix the problem ourselves or should we wait until Apple fixes it?
 
Upvote 0

Filippo

Expert
Licensed User
Longtime User
Now at least I have an error message after it has held the connection to the BLE device for 2 hours.
My question now is: what caused the error message?

B4X:
Private Sub btManager_Disconnected
    Log("Disconnected: " & LastException)
    Msgbox("Bluetooth Connection Is Broken"),"Bluetooth-Status")
    SetState(False)
End Sub

LastException:
Disconnected: <B4IExceptionWrapper: Error Domain=CBErrorDomain Code=6 "The connection has timed out unexpectedly." UserInfo={NSLocalizedDescription=The connection has timed out unexpectedly.}>
 
Upvote 0

Alessandro71

Well-Known Member
Licensed User
Longtime User
Now at least I have an error message after it has held the connection to the BLE device for 2 hours.
My question now is: what caused the error message?

B4X:
Private Sub btManager_Disconnected
    Log("Disconnected: " & LastException)
    Msgbox("Bluetooth Connection Is Broken"),"Bluetooth-Status")
    SetState(False)
End Sub

LastException:
Does it happen while data transfer is active?
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
Hi @JordiCP ,

In my app the problem comes already in the foreground.
The connection to the BLE device works without problems, but the connection is terminated after 1 or 2 hours.
Up until iOS 15.8 it never had any problems.
The question now is: can we fix the problem ourselves or should we wait until Apple fixes it?
No idea sorry. In my specific case, the connection doesn't need to be kept alive. The app searches for known devices and just connects with those against which it needs to perform some action (it allows manual or hands-free remote opening of several devices), then disconnects and continues scanning for 'known' devices.

Anyhow, if this happens (with iOS16 or with any other version, even if rare, disconnections can also happen for other reasons) a good solution would be to have some sort of 'connection manager' which tries to automatically reconnect when the BLE connection is broken so that the upper layers of the app don't have to deal with it.
 
Upvote 0

Filippo

Expert
Licensed User
Longtime User
a good solution would be to have some sort of 'connection manager' which tries to automatically reconnect when the BLE connection is broken so that the upper layers of the app don't have to deal with it.
Yes, a 'connection manager' could be a solution.
I am trying to develop such a solution now.

The error is only in iOS-16, before this version everything works perfectly! It's only my iPhone with iOS-16 that has problems, all other devices with an earlier version work without problems.
 
Upvote 0

Filippo

Expert
Licensed User
Longtime User
Hi,

this is the solution to my problem:
B4X:
Private Sub btManager_Disconnected
    Log("Disconnected: " & LastException)
    If Not(LastException.IsInitialized) Then Return
    If LastException.Domain = "CBErrorDomain" And LastException.Code = 6 Then 'Code=6 = "The connection has timed out unexpectedly"
        starter.hd.ToastMessageShow(starter.language.Value("strBluetoothConnectionIsBroken"), True)
        IsConnected = False
        'Versuche Verbindung wiederherzustellen.
        btManager.Connect(LastConnectetDivice.Mac)
    Else
        Msgbox(starter.language.Value("strBluetoothConnectionIsBroken"),"Bluetooth-Status")
        SetState(False)
    End If
End Sub

It also seems to work quite well, because even after turning off the BLE device and turn it back on, it automatically reconnects.
 
Last edited:
Upvote 0

Alessandro71

Well-Known Member
Licensed User
Longtime User
Looks like you’re emulating the starter service on iOS, probably for easy source sharing with B4A.
I’m doing the same for my apps.
 
Upvote 0
Top