iOS Geofence Clcircularregion Monitoring. Locationmanager:Didexitregion Does Not Seem to Work as Expected

iOS Geofence CLCircularRegion monitoring. locationManager:didExitRegion does not seem to work as expected

I don't think region monitoring will work well for such a small radius.

  • The best accuracy with the GPS chip and kCLLocationAccuracyBestForNavigation is often just 10 meters.
  • Apple says (in the Location & Maps PG) that the minimum distance for regions should be assumed to be 200m
  • I've heard that region monitoring is using WiFi to get it's position (which makes sense for power savings). WiFi accuracy is more like 20m-100m. I'm not sure how having another app using background location (i.e. using GPS) would affect this. Probably, the location manager would share information to make the accuracy better.
  • Region monitoring can take 30 seconds to fire once inside a region, and a couple of minutes to fire after leaving a region (to prevent location glitches from triggering it).
  • When region-monitoring was first introduced, they said that it would only work with 100m regions and anything smaller would be bumped up. This probably still happens.
  • There's a deprecated method startMonitoringForRegion:desiredAccuracy: which allowed you to specify the distance past the region border to start generating notifications. Presumably this feature has been rolled into startMonitoringForRegion: but is still there. A 10m region might end up with a 10m buffer.
  • If you want to do this, specify a larger region around where you want to monitor, and when the device wakes up in that region, start background location updates (GPS) and use CLCircularRegion's -containsCoordinate: to trigger when the device is within 10m manually. This method is officially sanctioned by Apple (see WWDC 2013 Session 307).

From the CLCircularRegion docs:

Remember that the location manager does not generate notifications immediately upon crossing a region boundary. Instead, it applies time and distance criteria to ensure that the crossing was intended and should genuinely trigger a notification. So choose a center point and radius that are appropriate and give you enough time to alert the user.

From the Location & Maps PG:

Region events may not happen immediately after a region boundary is crossed. To prevent spurious notifications, iOS doesn’t deliver region notifications until certain threshold conditions are met. Specifically, the user’s location must cross the region boundary, move away from the boundary by a minimum distance, and remain at that minimum distance for at least 20 seconds before the notifications are reported.

The specific threshold distances are determined by the hardware and the location technologies that are currently available. For example, if Wi-Fi is disabled, region monitoring is significantly less accurate. However, for testing purposes, you can assume that the minimum distance is approximately 200 meters.

There's further inside scoop from this post by Kevin McMahon, who asked the Core Location engineers about region monitoring at a lab at WWDC 2012. This info will have changed in the meantime, but the part about region categories is interesting. Here's an edit:

Fine Region (0 - 150m)

- With the floor of 100m this category's range is effectively 100-150m.

- For regions this size performance is heavily dependent on the location-related hardware

- The amount of time that it takes Core Location to detect and call the appropriate delegate method is roughly 2-3 minutes on average after the region boundary has been crossed.

- Some developers have figured out independently that smaller regions would see quicker callbacks and would cluster smaller regions to cover one large area to improve region crossing notifications.

didEnterRegion firing for all my geofences

The best accuracy with the GPS chip and kCLLocationAccuracyBestForNavigation is often just 10 meters.

Apple says (in the Location & Maps PG) that the minimum distance for regions should be assumed to be 200m

as pointed out by this answer - it will help but not please you

https://stackoverflow.com/a/23931552/2027018

(iOS) Multiple notifications via locationManager:didExitRegion: when exiting a region

tl;dr: It's really quite simple - you're getting as much information as Apple can give you about the fact that you're crossing cell tower boundaries - meaning, not really good data at all.

Now the real story:

Generally, there are only a couple of ways that CoreLocation can determine one's position:

  • By GPS. This is highly accurate (tens of meters), but takes lots of power to use.
  • By WiFi. This is generally accurate, though wifi base stations can and do change, which makes it fuzzy. This method cross-references the wifi stations in the area vs some known accurate locations - so it knows when it sees "FooWifiStation" that it's associated with a particular area, measured by precise instruments, or perhaps even other phones with GPS turned on (which is controversial, we may never know if Apple uses this method)
  • By cell tower locations. These don't move, so it knows you're within a big fuzzy dot of coverage when you're associated with a tower. This is the least accurate, but least power-consuming, because your phone is already doing the work to stay in contact.

You can even see this if you go into the maps application "cold": you start out immediately with a big fuzzy blue dot, (at least 1km where I am), then it shrinks as it gets a wifi location fix, then it more or less disappears when GPS gets its fix. It's doing [cell tower] => [wifi] => [gps] accuracies in real time.

From my experience, the "significant location change" clause means "We'll let you know whenever you move in a big way, as long as we don't have to do any more work or expend any more power to get you that data. This means de facto that the very best you can rely on is using transitions between cell towers. Apple deliberately left this vague, because if another app uses something that has better resolution - say, you open Maps.app, and it gets a GPS fix - it is possible that you will suddenly get a great fix on location, but you can't depend on that always being the case. You've asked for a "weak reference" to location.

Now think about what happens when you are wandering about in your car: your cell phone has to manage that transition. It gets handed off, talks to multiple towers at once, that sort of thing, to manage a seamless transition which must be viable while you are having a conversation. Just that is a pretty neat feat for any little box to do. Necessarily, this will cause you to see a bit of bounce in location updates, because, to the phone, you're vibrating between cell towers at this time as it negotiates the transition.

So what the radius really means is that you're interested in data of roughly that accuracy - but the API will not guarantee that you get updates within that radius. You can think of it as Apple saying, "We're going to bucket your accuracy into one of 3 groups - but we didn't give you an enumeration, because we want to reserve the right to develop better methods of fixing your location without you having to change your code". Of course, in reality, any real app will change if they change their method of getting location, because they are annoyingly vague about this location stuff.

In other words, you will get a location fix at the cell tower with some totally made up guess as to how good that accuracy is; when you move to the next tower, you will instantly jump to its location, with a similarly fuzzy fix - does that make sense? CoreLocation is telling you you're at the cell tower with accuracy of however far the cell tower's signal reaches; as you move to another tower, you will probably get the bounciness of the handoff.

So when it comes to it, to really do a good job, you have to assume that the data is one of "great", "ok", or "bad" and use other methods - like Kalmann filters - if you really need to have a better guess at where the user is. As a zeroth-order approximation, I would just debounce the callbacks based on the time of the update, which is given, and assume that the user isn't really leaping kilometers back and forth within a few seconds, but rather, travelling in the direction of the first new update.

Geofences Not Triggered By Walking Through Them

the order is (lat, lon) NOT (lon, lat)!!!!!!

UILocalNotification and region monitoring

Here a nice post about enabling location updates in iOS on the background:

Using CoreLocation

Also here an answer with a work around for adding more than 20 geofence regions:

Adding more than 20 geofence regions

Hope this helps.



Related Topics



Leave a reply



Submit