Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS how to reconnect to BLE device in background?

There are many related questions but (apparently) no answers. SO...

My iOS app does get updates from my BLE device while the app is in background. If I lose touch with the BLE device, then in centralManager:didDisconnectPeripheral: I call -[CBCentralManager cancelPeripheralConnection:] -- otherwise I will never reconnect to the lost peripheral. Then I call [(re)call -[CBCentralManager scanForPeripheralsWithServices:options:].

Logging shows me that the didDisconnectPeripheral call, and its contained calls, are both happening while in background. However, the reconnect only happens when the app wakes up from background.

So I am able to communicate with the connected BLE device while in background (yay!) but not to reconnect. This is quite important to my app, and (one would think) to other apps. Suggestions welcome.

like image 219
Andrew Duncan Avatar asked Nov 12 '14 02:11

Andrew Duncan


People also ask

How do I use the BLE scanner app on my iPhone?

To enter BLE peripheral mode, navigate to the "Virtual Devices" tab and tap on the "+" icon to create a virtual device. When the blue checkmark is checked for a device, your iOS device is advertising as that particular BLE peripheral.

How do I find my BLE device?

To locate a specific Bluetooth device using the app, look for it by name in the device list. If you do not see it, ensure the device is not already connected to your mobile device or anything else, because most devices will stop advertising when they are connected and LightBlue® will not be able to detect it.

Does Apple Watch support BLE?

Pairing Apple Watch with iPhone is secured using an out-of-band process to exchange public keys, followed by the Bluetooth Low Energy (BLE) link shared secret. Apple Watch displays an animated pattern, which is captured by the camera on iPhone.


Video Answer


3 Answers

Paul was correct, that I did not need to cancel the connection, and that I did not need to rescan, and that all I needed to do was call connectPeripheral. BUT... what I was not doing was this:

_manager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)];

I was passing nil for the queue, which meant my CBCentralManagerDelegate callbacks were running on the main thread.

like image 79
Andrew Duncan Avatar answered Oct 04 '22 04:10

Andrew Duncan


You don't need to cancel the connection - it is already disconnected You don't need to rescan for the peripheral - you have already identified your peripheral.

In didDisconnectPeripheral you can simply call

[central connectPeripheral:peripheral options:nil];

Core Bluetooth will reconnect once the peripheral is visible again

A complete sample is here - https://github.com/paulw11/BTBackground

like image 29
Paulw11 Avatar answered Oct 04 '22 05:10

Paulw11


I know you probably have everything figured out already. I my self stumbled on this issue as well. Doing the following alone would not completely solve the problem (at least for me):
[central connectPeripheral:peripheral options:nil];

Instead of "nil" for the options, you will need to provide "options" in the above method. There are other things you need to set up as well (such as info.plist for your app). After reading Apple's instruction on how to enable background bluetooth operation for an App. I was able to get it working and receiving events for connect,disconnect,update etc., even scan can work in the back ground. Not to repeat everything what the Apple document has written about, you can take a look at the following link:
Core Bluetooth Background Processing for iOS Apps

Hope this helps.

like image 22
us_david Avatar answered Oct 04 '22 03:10

us_david