How to reguraly send data to a BLE peripheral in background?

I'm working with Core Bluetooth in Swift 3 to connect and exchange data to a specific (custom made) ble peripheral.


If the user selects a specific mode in the aplication i need to send data (write characteristic) to the device on a regulary interval (each minute) or on a specific time even if the user opens another app or turn the screen off. If the app is active i can achive this with a scheduledTimer but it stops as soon as the app became inactive. There is any way to continue to send data to the peripheral if the app goes to foreground? Is this possible?

Accepted Reply

In iOS, apps in the background are given execution time in response to events they subscribe to (like Bluetooth events, location updates, push notifications, etc.).


There is no mechanism for an app to execute itself in the background based on a timer. A typical Bluetooth app will be given a short period of execution time whenever the corresponding Bluetooth device takes an action to interact with the app.


In your case, to send some data to the peripheral once a minute, the peripheral should be making the request from the app, therefore waking it up via the Bluetooth background capability. Once your app is woken up, it will be given a very short period of time to make the data transfer, and then it should yield back (return from the callback method) and get suspended again until the next event.


If the peripheral is continuously connected during the lifetime of the app, it can use a notifying characteristic to wake the app. If it is disconnected in between, it can then start advertising at the scheduled time and this will wake the app up if it has been suspended pending a scan command.


Keep in mind that for long term operations like this, it is quite crucial to make sure your peripheral follows the "Bluetooth Accessory Design Guidelines for Apple Products" to avoid premature disconnections and speedy discovery of the peripheral while the app is in a suspended state. You can find this document at: https://developer.apple.com/hardwaredrivers/BluetoothDesignGuidelines.pdf

Replies

In your Info.plist, add a row for Required Background Modes. The type will be an array.

On item 0, set the value to App Communicates using CoreBluetooth.

This should allow it to run in the background.

Thank you but i already have this setting but i believe (from my understanding of the documentation (see the Communicating with a Bluetooth Accessory on https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html)) that this works when the peripheral sends for example a notification that can woke up the app but doesn't work to send data from the app to the peripheral when the app is not active or am i wrong?

It should be doable. I have an app that uses a timer which initiates the reading of all BT charactertistics on the device and does so every 3 seconds. As far as I can tell, I can trigger any function within that timer regardless of whether or not I am reading or writing a BT charactertistic.

I use a timer to write the characteristic every minute but it only work if the app is active. As soon as i press the Home button (or lock the screen) the timer stops and i'm unable to send the characteristic to the ble device. Did you manage to read the characteristic with the timer in background? can you explain me more or less how you manage to do that so see if i find an solution? Thank you

In iOS, apps in the background are given execution time in response to events they subscribe to (like Bluetooth events, location updates, push notifications, etc.).


There is no mechanism for an app to execute itself in the background based on a timer. A typical Bluetooth app will be given a short period of execution time whenever the corresponding Bluetooth device takes an action to interact with the app.


In your case, to send some data to the peripheral once a minute, the peripheral should be making the request from the app, therefore waking it up via the Bluetooth background capability. Once your app is woken up, it will be given a very short period of time to make the data transfer, and then it should yield back (return from the callback method) and get suspended again until the next event.


If the peripheral is continuously connected during the lifetime of the app, it can use a notifying characteristic to wake the app. If it is disconnected in between, it can then start advertising at the scheduled time and this will wake the app up if it has been suspended pending a scan command.


Keep in mind that for long term operations like this, it is quite crucial to make sure your peripheral follows the "Bluetooth Accessory Design Guidelines for Apple Products" to avoid premature disconnections and speedy discovery of the peripheral while the app is in a suspended state. You can find this document at: https://developer.apple.com/hardwaredrivers/BluetoothDesignGuidelines.pdf

Thank you Gualtier! After some research i believe this is the way too so we are already talking with the device manufacturer to make changes on the peripheral.