We use iBeacons with the interval set to 100mS as per Apple documentation.
If we turn the iBeacons on / off, iOS will call the DidEnterRegion and DidExitRegion as expected with high reliability, and this works with our app in the kill state, background, and foreground all day long on every iPhone we test with. HOWEVER, if we walk towards / away from the iBeacons, we observe that occasionally DidExitRegion and DidEnterRegion are not called. We have even checked this by using DidDetermineState and sometimes we get the wrong state returned from iOS. The phone can be sitting right beside an iBeacon transmitting at 100mS intervals for an extended period of time and the phone doesn't know it is there. DidDetermineState will report that it's not there. We can also use DidDetermineState when there are no iBeacons around and it will return that the iBeacon is still in range when it is long gone - like hours or even days later it will STILL report that the iBeacon is present using DidDetermineState.
None of this strange behaviour is observed if we turn the iBeacons on/off using a power switch. It only happens if we walk towards / away from the iBeacons.
Sometimes (but not always) waking up the phone will cause it to immediately call DidEnterRegion (if the beacon is present and we walked towards it) or DidExitRegion (if the beacon is gone because we walked away from it). Often it will not correct the issue, leaving the iPhone thinking a specific iBeacon is present (using DidDetermineState) even after that iBeacon has been gone for hours or even days.
We seem to get 100% success when we turn the iBeacons on / off - regardless of app state it works perfectly. We get about 90-95% success when walking towards / away from the iBeacons. We have tested this behaviour with multiple iBeacons and multiple iPhones and it is repeatable. It's driving us insane.
This issue is causing extremely poor customer experiences, and it only exists on iOS devices. Our system runs perfectly on another platform.
Has anyone ever experienced anything like this? Could it be that our app is not handling some sort of error being returned from DidDetermineState correctly?