0

I'm working on a use case that needs continuous callbacks while scanning the beacons. I've thought of 2 approaches but they both have issues.

  1. Monitoring: Monitoring only gives entry and exit callbacks. There's a limitation of listening to only 20 beacons. Also is there a range that i can define to get entry and exit callbacks? Like say if a an advertising beacon comes in range of 2 meters i get an entry callback and if the device moves out of that range i get an exit callback.

  2. Ranging: Ranging gives continuous callbacks along with a set of other parameters like rssi to calculate distance. The big issue when it comes to ranging though is that it consumes insane amount of battery compared to monitoring. What should be an approach for getting continuous callbacks while optimising battery consumption?

I've tried both the approaches and reached to a dead-end. Hence it may seem like a theoretical question yet any insights to solve the use-case in some manner.

Deep Lathia
  • 750
  • 7
  • 18

1 Answers1

0

It is not possible to set any kind of rssi or distance filter when using iOS CoreLocation beacon monitoring APIs. Ranging is the only alternative when working with iBeacon.

While battery drain of constant BLE scanning is an issue, you an mitigate this by scanning on a lower duty cycle as needed to meet your requirements. For example, you can scan on a 20% duty cycle (and use 20% as much battery as constant ranging) by ranging for 12 seconds every minute. You can adjust this duty cycle as needed to balance your goals between battery savings and responsiveness. I have worked on projects where I change this duty cycle depending on app state, so the app can be more responsive to beacons when it is important and save battery when responsiveness is less important.

In order to be able to do this at all, you must unlock the ability to have iOS let your app run in the background for an unlimited time period as described in my blog post here:

  1. Add the location background mode to Info.plist
  2. Obtain "always" location permission from the user. It is not sufficient to get "when in use" permission.
  3. Start a background task as described here: http://www.davidgyoungtech.com/2014/11/13/extending-background-ranging-on-ios
  4. Request 3km location updates from CoreLocation. This will keep the app running in the background without extra battery drain from GPS, as 3km accuracy only uses the cell radio You don't need to do anything with these results. You just need to request them to keep the app alive.

Once you do the above, you can call locationManager.startRangingBeacons(...) and locationManager.stopRangingBeacons(...) on a timer to implement whatever duty cycle you want.

davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • As you suggested to run this on Timer, you mean NSTimer? As it involves active run-loop and it is difficult to operate these NSTimer in the background. Do you have any alternate solution for timer which runs in the background thread and where it repeats 5-15 secs to perform stop and start ranging. – iSalman Oct 31 '20 at 23:58
  • You can see an example [here](https://github.com/davidgyoung/OverflowAreaBeaconRef/blob/master/OverflowAreaBeaconRef/OverflowArea/FusedBeaconManager.swift#L263-L292) The highlighted code sets up a background task that runs in an infinite loop, waking up every 1.0 second to run code on the main thread. You can change this to be any interval you want, and change the code that executes periodically to stop/start ranging. – davidgyoung Nov 01 '20 at 00:24
  • Thanks, David! Could you suggest the best efficient way to stop/start ranging the beacons? Because I've tried stopping all ranging UUIDs(approx ~80) and starting it again at an interval of 20 seconds based on the example snippet code you've linked. But through that, battery consumption has increased even more. Also, I've used multiple other properties that stop/start updating the location which the location manager offers but that doesn't impact on stopping the ranged beacons to give callbacks when the stop range/location been called. – iSalman Nov 06 '20 at 14:18
  • I would try scanning for 10 seconds, then stopping for 110 seconds so you do one 10 second scan every 2 minutes. – davidgyoung Nov 06 '20 at 21:04
  • @davidyoung Is there anyway i can set an interval for scanning while doing ranging instead of running a background timer? – Deep Lathia Nov 09 '20 at 05:15
  • Unfortunately, no. Apple provides no such flexibility to their APIs. – davidgyoung Nov 09 '20 at 14:56