I have a program in SWIFT, that detects when a beacon or multiple beacons are out of range and based on
that it will perform something like saving some data into database and etc. Everything works well, however I do get lots of
false positive in a way that "didExitRegion" getting fired and few secs later "didEnterRegion" getting fired while I haven't been moved or etc.
I know this has lot to do with the tuning of the beacons and their qualities, but at this time I have come up with an alternative solution.
So I decided to use NSTimer to see if I am really off range or is it just a false positive that I am getting?
so when didExitRegion is getting fired, I start a NSTimer for 60 secs. If the 60 secs is up and didEnterRegion didn't get fire, then I know
I am really out of range and perform whatever data saving I need to do.
Otherwise if didEnterRegion is called within that 60 secs, then I'll assume it was a false positive and invalidate the
nstimer and not doing anything.
Everything works well as long as I am working with one beacon. The problem I have with timer is when multiple beacons go out of range. lets say first beacon is out of range, so didExitRegion is getting fire and start the NSTimer Let say 20 secs later second beacon is off range and again didExitRegion is getting fired and that one starts the NSTimer again. Now my NStimer is all out of synch and at that time, things are not working correct and the NSTimer continuously start itself when 60 secs is up and etc.
So my question is what is the work around this solution? How can I keep my nstimer in synch when is called again before is invalidated? Is there a better way to this solution? Again, I know a better quality beacons can help, but that is not an option for me at this time.
One solution is to keep a dictionary like this:
var pendingExits = Dictionary<CLBeaconRegion,NSDate>()
Each time you get a didExitRegion
call:
Only start the NSTimer
if the dictionary is empty -- otherwise, assume the timer is already running.
Add the region to the dictionary along with a new NSDate()
to set the timestamp of when it was added.
When you get a didEnterRegion
callback:
When the timer goes off:
Find the newest remaining timestamp (if any) in the dictionary. Start the timer to go off at that time plus 60 seconds.