24

I am using a NavigationController to display a list of geo-fences available to the user. At the top there is a global on/off switch that I would like to use to disable any fences registered with CoreLocation -startMonitoringForRegion.

My fences seem to be registering ok and working for the most part, but no matter how many times I disable the fences individually, I'm still getting the purple location arrow indicating that the system is still monitoring my location and/or fences.

When I disable my fences individually, this is how I'm doing it.

CLLocationCoordinate2D coord;
coord.latitude = [[settingsData valueForKey:@"latitude"] doubleValue];
coord.longitude = [[settingsData valueForKey:@"longitude"] doubleValue];
CLLocationDistance radius = [[settingsData valueForKey:@"radius"] intValue];
CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:coord radius:radius identifier:[settingsData valueForKey:@"name"]];

// remove this fence from system monitoring
[locationManager stopMonitoringForRegion:region];
[region release];

I've gone through all of Apple's documentation on CoreLocation and use of these methods and I'm at the end of my rope.

I've tried calling [locationManager monitoredRegions]; but it only returns the active fence and only when I have my detail view loaded up. I'm not able to call it any other place in my program and get it to return any of my fences, even though I know they should be active. If anyone has any advice where to go next, I'm all ears.

Bill Burgess
  • 14,054
  • 6
  • 49
  • 86
  • 5
    Do I get a badge for asking a question that everyone avoids like the plague? – Bill Burgess Aug 16 '11 at 15:27
  • Have you tried asking this on http://devforums.apple.com? – jtbandes Aug 23 '11 at 17:59
  • No, but I probably should. I'm not getting anywhere with it here. – Bill Burgess Aug 23 '11 at 18:40
  • The LocationReminders sample app from WWDC 2010 seems to imply that you need to pass the same instance of CLRegion to stop that you used to start. I am not able to test this at the moment. –  Aug 23 '11 at 18:54
  • I can unregister the region if I use the same region I created it with, but if I don't know which region is out there... how do I know which one to create to remove it. This problem has been kicking my butt and there isn't much out there on this. – Bill Burgess Aug 23 '11 at 20:25

3 Answers3

51

Or, a more simple solution:

for (CLRegion *monitored in [locationManager monitoredRegions])
    [locationManager stopMonitoringForRegion:monitored];
beryllium
  • 29,669
  • 15
  • 106
  • 125
thepaperboy
  • 676
  • 7
  • 6
  • 1
    I think you should also check for the region identifier, otherwise you might end up interfering with some other region(may be created by some library you might end up using later). Something like: `if([monitored.identifier isEqualToString:kGeofenceIdentifier]) { [locationManager stopMonitoringForRegion:monitored]; }` – Yogesh Maheshwari Feb 13 '15 at 23:55
  • where should i call stopMonitoring? if that same region come again it will monitor or not – iSrinivasan27 Nov 29 '18 at 10:27
13

Ok, I think I can answer my own question here finally. Does this mean I can claim my own bounty? :D

First off, the lingering location arrow seems to be an iOS bug. I have found multiple stories out there with the very same issue. So there won't be much I can do about that for now.

As far as removing all of my regions at once, I got this down pat now.

NSArray *regionArray = [[locationManager monitoredRegions] allObjects]; // the all objects is the key
for (int i = 0; i < [regionArray count]; i++) { // loop through array of regions turning them off
     [locationManager stopMonitoringForRegion:[regionArray objectAtIndex:i]];
}

I was able to display my array and proved they were all in there. Another check after removing shows they are all gone. Whew!! The issue of the location arrow remains depending on which version of iOS you are running. I can't that I guess. If you have users, make sure you inform them the purple arrow is not your fault. For more info on the issue, you can start here. GetSatisfaction Good luck.

Bill Burgess
  • 14,054
  • 6
  • 49
  • 86
  • 'allObjects' isn't acutally 'the key' - it's 'the value' :P That was your problem. monitoredRegion returns a NSSet object and not a NSArray :-) – jules Aug 25 '11 at 23:08
  • I didn't know that. It was never listed anywhere, not even in Apple's documentation. And I didn't mean key as in 'key', I meant it as in the key to me fixing it. – Bill Burgess Aug 26 '11 at 01:40
  • just have a look at the *.h file in cases like this. press CMD and click on the class name or method and XCode takes you to the according class. So you can figure out what kind of property monitoredRegions actually is. – jules Aug 26 '11 at 07:17
  • About the purple arrow staying visible - I tried disabling the regions in iOS 5.1, and it disappeared after some time. It looks like Apple might have fixed the. – Brandon O'Rourke Mar 29 '12 at 18:39
  • Yes, I believe they have. The arrow has changed with 5.1, it is now an outline for region monitoring, and solid for any location usage. There is a legend at the bottom of the location settings in the Settings app. – Bill Burgess Mar 29 '12 at 23:22
  • If monitoredRegions returns a NSSet and not an NSArray (which it does) then how does [regionArray objectAtIndex:i] work in the solution? It must be being cast into an Array, but I'm just double checking. – ari gold Aug 31 '12 at 22:37
  • [locationManager monitoredRegions] returns an NSSet. It is more like a crude NSArray. It doesn't have the ability to access an object at a specific index. You can loop them if you like. for (CLRegion *region in [locationManager monitoredRegions]), but you can't access them by index. If you want them in an array, you add the allObjects which returns them in an array which my example shows. Hope this helps. – Bill Burgess Sep 02 '12 at 13:37
3

Yes it is an iOS bug. Deleting and reinstalling the app does not help. The only way I managed to get rid of the problem is by resetting location warnings

honcheng
  • 2,014
  • 13
  • 14