Geofencing Rules

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?

Accepted Reply

UGH! turned out thought the order was (lon,lat) not (lat,lon) for the points!!!!

Replies

"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."


I found this in the documents. Does that mean if I create a geofence, and simply walk through it, that the region will never be triggered??


It seems unimaginable to think that scenario makes any sense?

how could a region that has been explicitly defined by the engineer to be meaninfgul and important, be redefined by the OS to be irrelevant?


In these instances I'm talking about walking dead through the entire region... the entire diameter's length.. through one end, through the center, and out the other side.


Is there therefore a scale at which this becomes viable?

Assume a user is walking through a city. If the regions are each scaled up to say.. 250m... meaning the user inhabits each region for a much longer time, would these then trigger notification? (I can and will of course do some experimenting if unknown).

Just tried something different...


Created 1 geofence centered around the user's last location.


CLRegion *workingGeoFence = [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(lastLocation.coordinate.longitude, lastLocation.coordinate.latitude) radius:80.4672 identifier:@"centered"];

workingGeoFence.notifyOnExit = YES;
workingGeoFence.notifyOnEntry = NO;

[locationManager startMonitoringForRegion:workingGeoFence];


The little outlined location icon appeared at the top of the screen (indicating the geofence was succesfully added of monitoring).


Waited maybe 30 seconds, then I walked from the center, directly out, through the boundary.... and nothing again...


not sure whether this matters but, when creating the geofence via

UIApplicationWillTerminateNotification
..
locationManager:didStartMonitoringForRegion:
never has a chance to be called before the app terminates.


But right after calling

startMonitoringForRegion:
, the geofence does appear in the
monitoredRegions
property

UGH! turned out thought the order was (lon,lat) not (lat,lon) for the points!!!!