Is there any way to "force" an iOS app (coded as a BLE Central) to continue to perform BLE scanning in the background as if it were running in the foreground? We are using the RSSI to determine proximity and the app must run in the background and process RSSI levels. NOTE: As you may or may not know, the RSSI is very noisy and needs to be filtered using as many samples as possible to get an accurate proximity. We have tried connecting and then immediately disconnecting the app to/from the BLE peripheral, however using this approach prevents the peripheral from advertising while connected to the the iOS app. This, in effect, limits the amount of advertising by the BLE peripheral that would be needed by other nearby iOS devices, so ideally, we would prefer to not use this method. For those who wish to weigh in on this question, we have access to modify any or all parts of the advertising payload by the BLE peripheral.
2 Answers
You cannot force an iOS app to do something that is against Apple's rules. If you want to continue scanning for BLE devices, your app needs to be in the foreground state.
Alternatively, your can monitor BLE devices in the background. Whenever a BLE device gets close to your device, you then get some limited time to scan for devices - also in the background.
let beaconRegion = CLBeaconRegion(proximityUUID: "some uuid", major: 1, minor: 1, identifier: "some identifier")
locationManager.startMonitoring(for: beaconRegion)
However, I don't know if this fits with your use case.
You can continue BLE scanning in the background using service UUID. You have to scan for specific service UUID. Use below method to scan in the background.
open func scanForPeripherals(withServices serviceUUIDs: [CBUUID]?, options: [String : Any]? = nil)
Another thing you need to set background mode in your .plist file. Set 'Required background modes' as 'App communicates using CoreBluetooth'.