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
Geofencing works by detecting a user moving from one cell network tower to another cell network tower.
Therefore smallest area you can define is dictated by how close together the cell towers are.
Inside a shopping mall or sports stadium, it might be able to do 10 metres — cell towers are often extremely close together. In a regional area anything smaller than 100km can fail.
If you need smaller areas, you need to use bluetooth instead of cell towers (iBeacons). If there is a bluetooth low energy device in the target area you can set the range to very short (centimetres) or reasonably large (up to 30 metres or so). Note this all depends on the quality of the iBeacon hardware, some are better than others.
Unfortunately bluetooth (version 4.0 or newer) and cell network towers are the only way to monitor locations without significantly draining battery. Keeping the GPS active to check for a 10 metre boundary would drain the battery from full to completely flat in about 2 hours even with the screen switched off.
Sounds like even 1 meter should work (and work better on iPhone 4S+ devices):
Based on @Nevan's answer, which indicated some sort of coverage in WWDC 2013 307 (which didn't directly address this), I came up with a reasonable solution to getting < 10m accuracy for the arrival to a location, though I have a feeling that implementing
-(void)locationManager:didVisit:
might make this more battery-conservative, but would provide less frequent updates.First, have some regions with 0..150m radius, and start monitoring. Doesn't really matter, as the system seems to trigger these at around 150~200m:
Then, implement
The system will start monitoring and reporting to your delegate a stream of locations, even if your app is suspended (need
UIBackgroundModes
to includelocation
array element).To check if one of those locations is within the centre of one of your regions, Implement:
You'll also want to implement:
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 intostartMonitoringForRegion:
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:From the Location & Maps PG:
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:
This seems to be a bug in
CLLocationManager
. I've done extensive testing using various region radius configurations andlocationManager:didExitRegion
does not fire in an expected way. This seems to be either a rather nasty bug or region monitoring does not happen at all like the documentation suggests. I have the test harness available to anyone who wants it:http://www.mediafire.com/download/x863zkttltyalk6/LocationTest.zip
Run it in the simulator and start the test by by selecting Debug -> Location -> Freeway Drive in the iOS simulator menu. The number you see is the distance from the center of the monitored region. The background color will be green while the device is within the monitored region and red when outside the region. The text below the distance are event logs.
After running the app, you should see
locationManager:didExitRegion
fire at 5319 meters from the monitored region. The route will loop every 37 minutes and you'll see the device exiting the region always at 5319 meters.I've submitted a radar with Apple (17064346). I'll update this answer once I hear back from them. At least then we'll have some input from the canonical source.
Here's the detailed text sent to Apple:
Ths issue does not seem to be related at all to the size of the region. According to the Apple docs, even small regions are supported:
Although region events don't happen instantaneously, they should happen fairly quickly. From the Apple docs:
This is not at all what I am seeing in the test harness. On the simulator the device will always be 5000+ meters away from the region before a
locationManager:didExitRegion
event occurs.I do agree with Michael G. Emmons, and want to share my experience too:
I tested my code with three regions as shown in the image below:
Explaining the behaviour:
Expected Behaviour: - Enter/Exit event should be triggered only when i am crossing the boundary of regions, or inside the regions, not before 500 meter from the region.
My Assumption:
So i think that all the regions inside 5000 meters are being detected, and as user moves away 10 km from detected region, its Exit event will be fired. otherwise if user is inside the 5Km range, it will never call it Enter/Exit events again.
Please update me on, if anyone has fixed this issue, or Apple documents anywhere about this issue.