I have been working on a prototype iOS app utilizing iBeacons to provide location-relevant information to office employees depending on where in the office they are. The ideal use case is that whenever an employee enters or exits their office, a callback is fired which provides them some information in the form of a notification (it might make a server query to get information first, etc - that sort of thing). We also want to be able to do this when the app is backgrounded or terminated; fortunately, we already know that beacon region boundary crossings trigger the appropriate CoreLocation callbacks even if the app is backgrounded or suspended.
From looking around, I understand that broadly, I have two options for how to approach the beacon region monitoring:
- Give each iBeacon its own CLBeaconRegion, and monitor for each of these regions independently.
- Monitor for CLBeaconRegions that correspond to multiple iBeacons - for example, each iBeacon has the same UUID and only monitor for a CLBeaconRegion corresponding to that UUID - then try to determine which beacon triggered the boundary crossing using ranging.
Thus far, I had chosen option #1. The advantage of this approach is that I get didEnterRegion: and didExitRegion: calls for each individual beacon and immediately know which beacon I have entered/exited. Also, I only get one enter call and one exit call, which is exactly what I want. Unfortunately, I just realized that this approach also limits me to 20 beacons (since each beacon gets its own region).
I'm not as familiar with the exact implementation details of #2, so correct me if I'm wrong. But it seems that this approach has more drawbacks:
- Apple discourages ranging when the app is in the background because the results may not be as accurate.
- The ranging calls fire once every second, while I only want to have "enter/exit" callbacks.
- If the beacons have region overlap, the ranging calls might continually flip which one is "closest", which would further complicate things.
Basically, I'm wondering if there is a way to utilize option #2, but still have the benefits of option #1 - a quick and easy way to immediately determine which beacon triggered the region change with only one enter or exit callback?
I hope this question is clear enough. It's not all entirely clear in my own head, especially how ranging works.