Search code examples
iphonexcodecore-locationregion

iphone CLLocationmanager Region monitoring callbacks not triggered


I am trying to use monitoring regions to track if users have visited landmarks. the location manager is initialized in a viewcontroller along with a mapkit

in viewdidload of the view controller:

if (self.locationManager == nil)
{
    //        NSLog(@"creating location manager");
    self.locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    locationManager.distanceFilter = kCLDistanceFilterNone;
}


NSSet* set=[locationManager monitoredRegions];

if ([CLLocationManager regionMonitoringAvailable] && [CLLocationManager regionMonitoringEnabled]) {
    NSLog(@"region monitoring okay");
    NSLog(@"monitored regions: %@",set);
} 

i get the NSLogs "region monitoring okay" and all the regions correctly.

adding of the regions are done like so

double metres=20.0;
CLLocationDistance dist=metres;
CLLocationAccuracy acc=1.0;

CLRegion *reg=[[CLRegion alloc] initCircularRegionWithCenter:coordinate radius:dist identifier:landmarkObj.landmarkName];

[locationManager startMonitoringForRegion:reg desiredAccuracy:acc];

but the callbacks are all not triggered

 - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Entered" 
                                                    message:region.identifier
                                                   delegate:self
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil, nil];
    [alert show];
}

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Exited" 
                                                    message:region.identifier
                                                   delegate:self
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil, nil];
    [alert show];
}

- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{
    NSLog(@"started monitring for region: %@",region);
}

- (void) locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{
    NSLog(@"%@",error);
}

updating the location however, works fine.

[locationManager startUpdatingLocation];

triggers the callback didUpdateToLocation as expected

Update: used didUpdatToLocation to monitor for regions instead. still interested to know why this would not work though, looks like few have had success with region monitoring


Solution

  • the region tracking stuff is for low granularity position tracking and is triggered on cell location boundaries, so if you don't cross a cell boundary, you will never get your regions checked. I had the same issues and researched this and a different website had a comment about this which pointed to this apple forum:

    https://devforums.apple.com/message/251046#251046

    If you read all the comments you will understand why this is not working.

    I am trying a work around where I define my own NSSets to contain tracked CLRegions and occupied CLRegions and then when I get a locationManager:didUpdateToLocation:fromLocation: callback, I check all the regions in my tracked set to see if I was NOT in the inRegions set but now am in the tracked region (add to inRegions and call back with enterRegion) or if I was inRegion but now am not (remove from inRegions and call back with exitRegion). It is a work in progress now.