How to BLE device will invoke the app, when app has terminated

Viewed 2045

I have a one BLE Device(Peripheral) and iOS Application which communicate to each other using CoreBluetooth.framework( connect, disconnect, subscribe, notify services). Here are the few scenario:

  1. The app is foreground -> I am very easily connected with BLE device.
  2. The app is in the background -> I get the callback and connect with the BLE device
  3. The app is removed from the background (Kill the app) -> I am not getting any callback even I connect the device from iPhone Device-> Settings-> Bluetooth on -> Select Ble Device -> Connect.

I google and get State Preservation and Restoration will be invoked the app. After deep drive : enter image description here enter image description here enter image description here

This also showing App Force Quit by the user , app will not relaunch or active using state preservation and restoration.

I read from this, this and this, have some points :

"If you need to execute code when your app isn’t running, there are several options open to you depending on what you’re trying to do. - Background fetch will let your app run in the background for about 30 seconds at scheduled intervals. The goal of this is to fetch data and prepare your UI for when the app runs next. - Push notifications let your app fetch fresh data from your server. You can make a message appear on the device if you want, but it’s not required – silent push notifications let you skip that part. - Local notifications let you display an alert to the user, along with any media attachments you want and some options for the user to select from. If they choose those options then your app can be launched in the foreground or background to handle them."

I tried with Background Fetch, but it's also not awake when the application has been terminated.

My single objective to achieve is "When the application has terminated or killed by the user, Whenever BLE Device is connected the app should be invoked in foreground/background so that I will perform some operation like get the data from BLE Device and save it"

Using background modes in a project: enter image description here

Other BackgroundModes also not gives any clue: enter image description here

How can achieve this without using push notification or silent notification? if anything in CoreBluetooth framework where the application awake after the termination, let me know?

2 Answers

The short answer is, you can't.
The documentation clearly states that your app will not be relaunched when it is explicitly killed by the user.
This is true for silent notifications as well - these will not wake your app up if the user had forced terminated your app (or the device battery state is below 20%, btw).
Your options for this are limited, and may include advising the user not to force kill your app, or using location based region detection to re-launch your app.
One of the tutorials you've linked shows an iBeacon example to detect going in and out of range of iBeacons, and when combined with background permission can relaunch your app, but again - this isn't explicitly what you've asked for and is not a real solution to the problem you describe.
Apple's logic is simple - if the user kills your app, the user doesn't want it to run again, which makes allot of sense.
The thing is, many users think that killing apps is the standard way to make their device more responsive, there's a big debate on this (what's worse? having the OS cold start apps or allowing apps to do funny stuff in the background with silent notifications, etc.) I won't go into that debate, that's just the way it is.

This is Abstract code to highlight the solution. You might need to tweak few things.

1> Create CLBeaconRegion with UUID start monitoring for that beacon

locationManager.requestAlwaysAuthorization()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.startUpdatingLocation()
    locationManager.startMonitoringSignificantLocationChanges()
    if let uuid = UUID(uuidString: "B9407F30-F5F8-466E-AFF9-25556B57FE6D") {
           let beaconRegion = CLBeaconRegion(proximityUUID: uuid,identifier:"iBeacon")
           beaconRegion.notifyOnExit = true
           beaconRegion.notifyOnEntry = true
           locationManager.startMonitoring(for: beaconRegion)                       
    }

2> As per the document

If you begin monitoring a region and your app is subsequently terminated, the system automatically relaunches it into the background if the region boundary is crossed

Reference

3> Your peripheral should transmit as ibeacon who transmit same UUID (Same UUID for which you have created CLBeaconRegion)

You might need to play with few parameters of CLLocationManager and CLBeaconRegion but this should work in my opinion because in the past my apps have been successfully woken up from terminated state on iBeacon detection ....

Related