I coded up something pretty simple:
When a user terminates the app, I create geofences around the user's last location, so that I can be notified when the user leaves that location.
double LON_DEGREES_PER_CITY_BLOCK = LAT_DEGREES_PER_CITY_BLOCK/cos(DEGREES_TO_RADIANS(lastLocation.coordinate.latitude));
double workingLonShift = 0.0, workingLatShift = 0.0;
NSString *workingLabel = @"";
CLRegion *workingGeoFence;
for (int a = 0; a < 8; a++) {
if (a == 0) {
workingLabel = @"north";
workingLatShift = LAT_DEGREES_PER_CITY_BLOCK * 2.0;
workingLonShift = 0.0;
}
else if (a == 1) {
workingLabel = @"northeast";
workingLatShift = LAT_DEGREES_PER_CITY_BLOCK * 2.0;
workingLonShift = LON_DEGREES_PER_CITY_BLOCK * 2.0;
}
else if (a == 2) {
workingLabel = @"east";
workingLatShift = 0.0;
workingLonShift = LON_DEGREES_PER_CITY_BLOCK * 2.0;
}
else if (a == 3) {
workingLabel = @"southeast";
workingLatShift = -LAT_DEGREES_PER_CITY_BLOCK * 2.0;
workingLonShift = LON_DEGREES_PER_CITY_BLOCK * 2.0;
}
else if (a == 4) {
workingLabel = @"south";
workingLatShift = -LAT_DEGREES_PER_CITY_BLOCK * 2.0;
workingLonShift = 0.0;
}
else if (a == 5) {
workingLabel = @"southwest";
workingLatShift = -LAT_DEGREES_PER_CITY_BLOCK * 2.0;
workingLonShift = -LON_DEGREES_PER_CITY_BLOCK * 2.0;
}
else if (a == 6) {
workingLabel = @"west";
workingLatShift = 0.0;
workingLonShift = -LON_DEGREES_PER_CITY_BLOCK * 2.0;
}
else if (a == 7) {
workingLabel = @"northwest";
workingLatShift = LAT_DEGREES_PER_CITY_BLOCK * 2.0;
workingLonShift = -LON_DEGREES_PER_CITY_BLOCK * 2.0;
}
workingGeoFence = [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(lastLocation.coordinate.longitude + workingLonShift, lastLocation.coordinate.latitude + workingLatShift)
radius:80.4672
identifier:workingLabel];
workingGeoFence.notifyOnExit = NO;
workingGeoFence.notifyOnEntry = YES;
[locationManager startMonitoringForRegion:workingGeoFence];
}
#if DEBUG
for (CLRegion *workingRegion in locationManager.monitoredRegions) {
LOG(@"workingRegion = %@", workingRegion);
}
#endif
And in that log loop afterwards, all of the regions I added are now in the monitoredRegions property... the only thing is... the geofences are never triggered.
I'm calling the above method in response to this notification:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(enterTerminatedMode)
name:UIApplicationWillTerminateNotification
object:nil];
This is for GPS only devices, FYI.
I read that 100m is the minimum a geofence can be, but that when a radius is made smaller than 100m, that it is just bumped up to 100m. Maybe this is resulting in overlapping geofences that get rejected?
Is there some kinds of restrictions I'm not accounting for, and thus the OS is silently rejecting my geofences?