I am working on a project where a stationary iPad will act as a BLE peripheral and an iPhone will act as a BLE central. As the iPhone enters within a few meters of the iPad, the iPhone will do something. The iPhone needs to be able to run in the background or locked.
I've been working with the CoreLocation library to create an iBeacon. Using ranging methods, CoreLocation allows me to find the accuracy and proximity of the beacon. However, from what I've found, CoreLocation does not allow for background ranging. I've also found that monitoring for a beacon region can trigger enter/exit events which allows me to launch the app temporarily (~5 seconds) to then range for accuracy and proximity. However, this solution would not work as the iPad's beaconing range is very large, and the central device would trigger the enter/exit events long before the device reaches my target range (a few meters of the peripheral).
Thus, I've been looking into the CoreBluetooth library as an alternative to CoreLocation/iBeacons. I am aware that using CoreBluetooth, I would have to manually calculate the distance based on the RSSI.
My first question is, Are my assumptions correct? Would CoreBluetooth be a good alternative to use for this project?
My second question is, Can the iPhone (central) determine the distance between itself and the iPad (peripheral) while locked or running in the background?
Thanks in advance!
CoreBluteooth is generally a poor substitute for CoreLocation for detecting beacons for a number of reasons:
You cannot detect iBeacon transmissions at all with Core Bluetooth. Apple explicitly blocks you from doing this, blanking out advertising data in the CoreBluetooth APIs if the advertising data matches iBeacon.
The ability to detect other beacon formats with CoreBluetooth in the background is poor. Manufacturer advertisements (like AltBeacon) are blocked almost entirely in the background (you can detect only one packet!). Service advertisements (like Eddystone) are detectable in the background, but callbacks are very slow relative to what you get with CoreLocation.
Lots of other CoreLocation features are missing like app auto-launch on beacon detection, and hardware filters to get fast background detections when your app is suspended.
You actually can range beacons in the background using CoreLocation a few different ways:
Options 2 and 3 above are available with CoreLocation but not CoreBluetooth. To get into the AppStore with option 3, you must convince Apple reviewers that your app is providing a legitimate background location tracking function.
Finally, you can do your own distance calculation based on the CLBeacon#rssi property. It is best to average it over 20-30 seconds to reduce noise, and you'll somehow need your own reference value for what the expected RSSI is at 1 meter, as the one embedded in the beacon frame is not readable by third party software. But you may not need to do this. If you are simply targeting iPads with your app, you can simply adjust the calibration constant inside the beacon with the expected 1 meter distance RSSI for your iPad, and you should get more accurate distance measurements.
There are some cases where you still want to use CoreBluetooth despite the drawbacks above. For that reason, I built this repo.
It is also possible to use advanced techniques like forcing screen on events to read RSSI from "Overflow Area" advertisements using CoreBluetooth.