Alex Blair
Alex Blair

Reputation: 614

Multiple Local Notifications glitch from didEnterRegion:

I'm Currently monitoring several locations that are backed by core data. In other words, I have set up a for loop that loops through all of the stored entities in core data and creates a monitored region for all of the entities.

The problem here is that the for loop triggers multiple local notifications when entering one of the regions. The number of notifications almost directly corresponds to the number of monitored regions. So I'm fairly confident this may be whats causing the bug, but I'm not 100 percent sure.

I've noticed that this seems to be a common issue with region monitoring, but I haven't been unable to find an example that incorporates a for loop.

How can I stop multiple notifications being triggered when didEnterRegion gets called?

The method below is called in viewDidLoad. The [DataSource sharedInstance].fetchedResultItems is an array that is populated with the fetchedObjects from a fetched request.

-(void)startMonitoringRegions{
    if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
        [self.locationManager requestWhenInUseAuthorization];

        CLAuthorizationStatus authorizationStatus = [CLLocationManager authorizationStatus];
        if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways ||
            authorizationStatus == kCLAuthorizationStatusAuthorizedWhenInUse) {
            self.locationManager.distanceFilter = 10;
            [self.locationManager startUpdatingLocation];

            for (POI *items in [DataSource sharedInstance].fetchResultItems){

                NSString *poiName = items.name;
                NSNumber *poiLatitude = items.yCoordinate;
                NSLog(@"value: %@", poiLatitude);
                NSNumber *poiLongitude = items.xCoordinate;
                NSLog(@"value: %@", poiLongitude);

                NSString *identifier = poiName;
                CLLocationDegrees latitude = [poiLatitude floatValue];
                CLLocationDegrees longitude = [poiLongitude floatValue];
                CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake(latitude, longitude);
                self.regionRadius = 10;

                self.region =  [[CLCircularRegion alloc] initWithCenter:centerCoordinate radius:400 identifier:identifier];
                [self.locationManager startMonitoringForRegion:self.region];
                NSLog(@"region: %@", self.region);
                NSLog(@"monitored regions %@", self.locationManager.monitoredRegions);

            }
        }
    }
}

Here is the didEnterRegion method

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
    NSLog(@"entered region!!");
    UILocalNotification *localNotification = [[UILocalNotification alloc] init];

    if (localNotification) {
        localNotification.fireDate = nil;
        localNotification.alertBody = [NSString stringWithFormat:@"You are near %@", self.region.identifier];
        localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
        localNotification.timeZone = [NSTimeZone defaultTimeZone];
    }
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
//    [[UIApplication sharedApplication]presentLocalNotificationNow:localNotification];
}

Upvotes: 0

Views: 113

Answers (2)

MirekE
MirekE

Reputation: 11555

Just a troubleshooting tip. You can use Obj-C equivalent of the following to see what regions are currently being monitored by the app. Perhaps reviewing the identifiers will shed some light on the problem.

for region in locationManager.monitoredRegions {
            debugPrint(region.identifier)
}

And for a clean start you can delete all regions with this:

for region in locationManager.monitoredRegions {
            locationManager.stopMonitoringForRegion(region)
}

Upvotes: 0

Manu Jose
Manu Jose

Reputation: 131

Regions are act as a shared resources. When you enter any region a call will be forwarded to all of the location manager. I think somewhere somehow you are creating multiple location manager objects. That is actually causing the multiple calling of didEnterRegion. The number of time didEnterRegion is called depending upon the number of LocationManager you registered. You should write the code in AppDelegate, in this method

  • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

//Place your code here

}

Upvotes: 2

Related Questions