I am currently trying to get my app to monitor particular regions using CoreLocation
however I am finding that it does not seem to work as expected, it seems to me that it cannot work with small a small radius set for each location i.e. 10m.
I've also put together a little test app which plots the circle radius on a map so I can visually see what is happening.
The code I am using for monitoring locations is as follows:
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// Set-up a region
CLLocationDegrees latitude = 52.64915;
CLLocationDegrees longitude = -1.1506367;
CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake(latitude, longitude);
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:centerCoordinate
radius:10 // Metres
identifier:@"testLocation"];
[self.locationManager startMonitoringForRegion:region];
I have not put up the code here for DidEnter
region etc as I know that works when I go over 100m away from the monitored region.
Here is a screen shot of the app when I am well over 10 meters away from the purple location on the map, the did exit region events do not fire, however if I switch my location to London it fires and also when I set my location back to where the blue location is currently it also fires.
Does anyone know if there is a limitation with the minimum region radius at all or perhaps I am doing something wrong.
Thanks Aaron
I don't think region monitoring will work well for such a small radius.
kCLLocationAccuracyBestForNavigation
is often just 10 meters. 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.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.