Background Mode for BLE app

We have a BLE app and we are trying to get it to work in Background Mode consistently.

Use case:

  1. RFID BLE reader is attached to a printer
  2. Person installs the iOS app on phone and enables Background Mode
  3. Person walks to the printer with phone
  4. iOS App connects to RFID BLE reader and authenticates to allow secure printing

Current status/Problem:

On several tests, we were able to connect to the BLE device, but with inconsistent results.

For example, for 5 - 2 min tests - (1) we see 8 successful scans, (2) 1 successful scan, (3) 20 successful scans, (4) 15 successful scans, and (5) 11 successful scans.

In the above tests, we were getting a scan every 3-4 secs and then it scanning stops.

The objective is to maintain continuous scanning until user closes app or disables background mode.

Why does scanning stop? How can we make scanning continuous?

Any guidance you can provide is appreciated.

I do not understand what you mean by "successful scans", and how are you determining that the scan stops after 3-4 seconds?

Things will be different for different configurations, but let's for now assume your configuration is the most common one:

  • app is central
  • the reader is peripheral

When you start a scan on the app, if you have the Uses Bluetooth LE Accessories background capability enabled, the scan will continue indefinitely until either you stop it in code, or the user does something like terminating the app, turning off Bluetooth, etc.

The way to determine whether the scan is running or not is via the CBCentralManager's isScanning()function. If you are calling that, and is returning false, and you have not stopped the scan yourself, then the other explanation is that you are somehow destroying your CBCentralManager object - either by overreleasing it, re-initializing it, or somehow overwriting it with another object which is not currently scanning.

If you are not actually calling isScanning() and assuming the scan has stopped because you are not getting callbacks to didDiscoverPeripheral() more than likely the issue is with the advertising.

Also, is the app in the foreground or background when this happens? How long before the scan "stops"? If in the background, how have you implemented your scanning logic? Apps in the background will only receive a single callback to didDiscoverPeripheral(). If you are getting more in the background what have you done to accomplish that?

Thanks for the response.

It's running in the background when scanning stops. The scan stops randomly after 8 successful scans, sometimes 20 scans, etc. I define successful scan as being able to connect to the peripheral and write badge id (authenticate).

We added a call to the iscanning() function, but scanning still stops.

Here's portion of the Flutter code:

    func startBackgroundTask() {
        // Start BLE scanning or other background tasks
        if centralManager?.state == .poweredOn {
            print("isscanning")
            centralManager?.scanForPeripherals(withServices: nil, options: nil)
        } else if centralManager?.isScanning == false {
            print("isscanning off")
            print("Scanning failed, restarting background task")
            restartBackgroundTask()
        } else {
            print("Bluetooth is not powered on")
        }
    }

    func restartBackgroundTask() {
        // Restart BLE scanning or other background tasks
        stopBackgroundTask()
        startBackgroundTask()
    }

    func stopBackgroundTask() {
        // Stop BLE scanning or other background tasks
        centralManager?.stopScan()
    } 

Background Mode for BLE app
 
 
Q