What Exactly Can Corebluetooth Applications Do Whilst in the Background

What exactly can CoreBluetooth applications do whilst in the background?

Nobody seemed to know, so I bought an iOS developer account and ran some experiments. Here's what I found:

When running in the foreground, you can start a scan using CBCentralManager::scanForPeripheralsWithServices. Your scan can be restricted to devices advertising a particular service, or unrestricted (pass nil for that call's parameter). It can also allow or disallow duplicates; in the former case you'll get a didDiscoverPeripheral callback every time the iPhone receives an advertisment packets; in the latter you'll only get one callback per device found.

When you enter the background, the rules appear to be as follows:

  • If you were running an unrestricted scan, it will be silently cancelled. You will not get any didDiscover callbacks.
  • If your scan was restricted (i.e. you specified one or more service UUIDs you were looking for), your scan will continue to run, but the allow duplicates flag will be ignored. This means that you will now only get didDiscoverPeripheral callbacks for new devices. If all devices were seen whilst in the foreground you will get no callbacks at all.
  • Starting and stopping the scan does not reset which devices are considered new. If there is one device present, you will only get a single callback, even across multiple scans, unless...
  • If you connect to a device, then disconnect, then scan again, the device will be enumerated again (i.e. you will get one more call to didDiscoverPeripheral). I guess iOS regards that as having "shown interest" in the device.

I don't know whether connect attempts to nonconnectable devices (e.g. BLE Advertisers, like those implementing the proximity profile) is good enough as my example devices are connectable. However at least for connectable devices, this scan/connect/disconnect/scan procedure suffices to poll for a device's presence in the background.

The above results were gathered using an iPhone 4S running iOS 5.0.1

App communicates using CoreBluetooth in background

Detecting the disconnection and reconnecting to the peripheral will make your app more robust as it will handle the case where the peripheral goes out of range and then returns in addition to the case you are seeing.

When the peripheral is disconnected your centralManager:didDisconnectPeripheral method will be called on your delegate. In this method you can call connectPeripheral:options again to re-establish the connection. iOS will either do this immediately if the device is still in range or automatically later, once the device comes back into range.

Once your centralManager:didConnectPeripheral method is called you can re-establish the characteristic monitoring.

Edit Clarify that you can call connectPeripheral immediately

Core Bluetooth and backgrounding: Detection of a device and triggering an action, even after being days in background mode?

No, iOS gives no guarantee that your app keeps alive in the background. The docs say:

However, this method may be called in situations where the application is running in the background (not suspended) and the system needs to terminate it for some reason.

(Documentation of applicationWillTerminate)

CoreBluetooth to detect accessory proximity (whilst app in background)

Yes, it is a valid approach to use CoreBluetooth as you describe. You can get a callback for each packet you detect in the foreground (and in the background for non-manufacturer advertisements). You can then read the RSSI as an indicator of proximity.

Whether you want to use CoreBluetooth or use iBeacons with CoreLocation, the battery usage is similar in most foreground ranging cases.

If using CoreBluetooth, you probably don't want to keep getting callbacks for every packet indefinitely in the background, because it would drain the battery faster. CoreLocation iBeacon APIs limit you to 10 seconds of ranging in the background for each wakeup event to help save battery.

If you see your app ranging for longer periods in the background using CoreBluetooth you may want to add your own logic to protect against battery drain.

CoreBluetooth background execution 10sec?


Does this mean that after 10 sec the app will go back to its
"suspended" state ?

If you read carefully :

Upon being woken up, the app has around 10 seconds to process the
data. Ideally, it should process the data as fast as possible and
allow itself to be suspended again. However, if more time is needed,
the app can use the beginBackgroundTaskWithExpirationHandler: method
to request additional time; it should do so only when absolutely
necessary, though.

Apps generally awake by Background modes(like location service, audio, push notification and so on) and for some modes like location service it will stay awake until the location data is being captured and for some, it doesn't stay awake for much time like push notification. So it depends on the task that is being performed. For Bluetooth, if it's connected with another Bluetooth device then it will stay awake.

Theoretically, is it possible to "force" the app to stay awake after
these 10 sec ? (private app).

Yes, it's possible.

Each of the preceding modes lets the system know that your app should
be woken up or launched at appropriate times to respond to relevant
events. For example, an app that begins playing music and then moves
to the background still needs execution time to fill the audio output
buffers. Enabling the Audio mode tells the system frameworks that they
should continue to make the necessary callbacks to the app at
appropriate intervals. If the app does not select this mode, any audio
being played or recorded by the app stops when the app moves to the
background.

Note : If you need it for your private app then you can check this here. Your app will be rejected if you add the solution and apply for appstore.

iOS : Keeping application alive in background while waiting for a connection

You don't. iOS watchdogs are prepared to free up as many resources as possible to ensure the proper execution of the foreground application. Since your application is no longer in the foreground, iOS will allow the app to run the necessary services, as long as it has enough resources to do so. I've had similar problems with location services running in the background.

Check the memory footprint of your application while running in the background. Release stuff you do not need. This will decrease the frequency in which your app is killed.



Related Topics



Leave a reply



Submit