Missing Every Other didExitRegion Event from LocationManager while iPhone is asleep

Preface:
  • location is set to always.

  • monitoring has been started with the iBeacon UUID to be monitored.

  • App service is running in the background

Problem:
Not always receiving entry events when our product first starts transmitting advertising packets. Upon further investigation it was determined that this was because we didn't always receive the exit event after our product was done transmitting. Therefore, we don't see an entry event from the same UUID.

Our missed events occur when the phone is asleep. Testing was done with the product sending advertising packets every 5 minutes or so for 30 seconds. In addition, exit events are not missed while the phone is plugged in and charging, but still asleep.

When our app fails to receive the didExitRegion at the end of the previous transmission from the location manager and our device starts transmitting the beacon again, we don't see the didEnterRegion, however at the end of this subsequent transmission, we do get the didExitRegion Event. Hence the cause of the every other transmission receiving the didExitRegion.

Questions:
Does the locationManager function differently depending on if the phone is plugged in vs unplugged while asleep?

What methods can we implement in our app to ensure exit events are captured ~(30 - 40) seconds after our iBeacon has stopped transmitting even while the phone is asleep and unplugged?

Thanks!

Replies

If you are missing entry events while the phone is unplugged an asleep this is likely that the advertising is incorrect.

If you are not advertising at a 100ms interval, you must fix that first of all.
If you are seeing the issue while advertising at 100ms intervals, then 30 seconds is not long enough for your use case.
Discovery of advertisements is a probability curve, and you would need to adjust the duration of the advertising period depending on the use case and your ability to manage the risk of discovery failures.

If iOS is not discovering the entry state, it will not report the exit state. Those go hand in hand.

We had a similar issue with iBeacons and it only started happening since iOS 13. Apple changed something in their scanning algorithms, most likely to further optimize battery consumption. We found that it was much more sensitive to the consistency of the advertising interval. So while you may be advertising at 100mS, you need to clock that 100mS and make sure it is really tightly controlled or the phone is going to miss it and do strange things.

We also resorted to using requestStateForRegion whenever possible. I know this doesn't help when you're trying to use the DidEnter / Exit as a trigger to wake up your app, but thought I would mention it.

I also know that most iBeacons will transmit as "connectable" for the first XX seconds, and then switch to "not connectable", which is what Apple recommends. One software developer I spoke with mentioned that if the iPhone is nearby when the iBeacon turns on and transmits as "connectable" and then changes to "not connectable" it can confuse the phone - making behaviour again unpredictable.

To this day it still happens to us on very rare occasions - DidExitRegion just flat out gets missed. We have even installed the bluetooth and location profiles on phones in an attempt to catch the behaviour and send the logs to Apple for analysis but we could never catch it because it happens so rarely to us.

If you find a solid root cause please post. Would be curious to hear what you discovered.