Core Bluetooth and backgrounding: Detection of a d

2019-01-21 03:09发布

问题:

I've written an app that needs to get informed when a certain Bluetooth Low Energy device comes within range. If the BLE device gets noticed my app just stores a timestamp.

As stated in the WWDC 2012 Core Bluetooth videos, there are two possibilities for apps for acting in background mode when working with Core Bluetooth:

Event Backgrounding

Event backgrounding is probably what most Apps will use when interacting with Bluetooth Low Energy devices. This mode does not allow for direct communications to the accessory when the App is in the background, but does provide for a notification from the accessory when it wants to communicate with the app. iOS will stay connected to the BTLE accessory when your App is in the background and will continue to monitor for notifications. When the connected BTLE accessory has a notification available, iOS will notify the user that the accessory would like to talk to your App, allowing the user to load your App and interact with the accessory. As many devices need to conserve power, only providing information at deterministic times will greatly enhance the battery life of the accessory and the iPhone 4S.

  • No info.plist entries are required for this mode.

Session Backgrounding

There are times where an App must interact with an accessory even if it is running in the background. Consider a running app that needs to monitor heart rate real-time. There is a clear START and STOP to this model. The user STARTS their run in the App. While the run is active, the App reads heart rate information until the run is completed or STOPPED. Session backgrounding also allows for scanning and connection to BTLE accessories while the App is in the background. A scanForPeripheralsWithServices or connectPeripheral call will continue, even when the App is in the background. CoreBluetooth will continue to monitor for specific peripherals or peripherals that match the services your App is looking for and call your Apps delegate when found or connected. Be mindful, that every time a BTLE peripheral or iPhone 4S uses its radio, it is depleting the respective devices available power. App developers using session based backgrounding must be mindful of power usage.

  • Session backgrounding requires a backgrounding mode entry to UIBackgroundModes, bluetooth-central, in your Apps info.plist.

Until now I Session Backgrounding (with the according info.plist entry). The app asks iOS to retrieve all known devices and then gives the connect command to the device I'm looking for. The connection callback comes even after minutes after my app was backgrounded.

But: the app gets suspended after - let's say - one hour. This means that the next time my app gets launched by the user, it cannot tell if there have been any sightings of the BLE device of interest.

So my question is: Is it possible for my app to get notified without user interaction even days after being sent to background when a certain BLE device comes in range so I can store my time stamp?

回答1:

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)



回答2:

As of iOS 7, your use case is now easy to support. Before iOS 7, your application could register for notifications about that peripheral, and it would be woken up in the background when the system had notification to deliver. However, if the system came under memory pressure while your app was backgrounded, or was rebooted, it wouldn't be relaunched. iOS 7 added state restoration to CBCentralManager and CBPeripheralManager, so now the OS will relaunch your application in a limited capacity even if it wasn't running due to either of the aforementioned conditions. See the CoreBluetooth guide for more info.

In short, for your use case, you could do the following:

  • Continue to support bluetooth-central as a background execution mode.
  • Opt into state preservation and restoration, as documented here under "Adding Support for State Preservation and Restoration".


回答3:

Use IOS7 BLE State Preservation & Restoration

If your app is terminated by IOS, due to memory pressure(this is why your app can't work after days), it can't handle bluetooth delegates anymore. In this case, if you used State Preservation & Restoration, your app can be relaunched to background to run again, also for only 10s. After 10s, it would move to suspended state. Only in this situation, CBCentralManager's willRestoreState can be triggered.

Good luck.