I have created multiple geo-fence to monitor region entry/exit events.
I have created a location manager in AppDelegate.h
file.
@interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate>
@property (strong, nonatomic) UIWindow *window;
@property(nonatomic,retain)CLLocationManager *locationManager;
@property(nonatomic,retain)CLLocation *currentLocation;
+(AppDelegate *)sharedDelegate;
AppDelegate.m
file
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (notification) {
NSLog(@"AppDelegate didFinishLaunchingWithOptions");
application.applicationIconBadgeNumber = 0;
}
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)])
{
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeAlert|UIUserNotificationTypeSound) categories:nil];
[application registerUserNotificationSettings:settings];
}
else // iOS 7 or earlier
{
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
}
if (!self.locationManager)
{
self.locationManager = [[CLLocationManager alloc] init];
}
self.locationManager.delegate = self;
//locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.locationManager.distanceFilter = 2.0f;
self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
[self.locationManager requestAlwaysAuthorization];
}
if ([self.locationManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)])
{
self.locationManager.allowsBackgroundLocationUpdates = YES;
}
if ([self.locationManager respondsToSelector:@selector(pausesLocationUpdatesAutomatically)])
{
self.locationManager.pausesLocationUpdatesAutomatically= NO;
}
[self.locationManager stopMonitoringSignificantLocationChanges];
if ([CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] != kCLAuthorizationStatusDenied)
{
[self.locationManager startUpdatingLocation];
}
// Override point for customization after application launch.
return YES;
}
-(void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{
NSLog(@"Started monitoring %@ region",region.identifier);
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
NSLog(@"%@",[locations description]);
}
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
dispatch_async(dispatch_get_main_queue(), ^{
if ([[UIApplication sharedApplication] applicationState]==UIApplicationStateBackground || [[UIApplication sharedApplication] applicationState]==UIApplicationStateInactive)
{
UILocalNotification *localnotification = [[UILocalNotification alloc]init];
localnotification.fireDate=[NSDate dateWithTimeIntervalSinceNow:1];
localnotification.alertBody=@"You are enter in region.";
localnotification.timeZone=[NSTimeZone defaultTimeZone];
localnotification.repeatInterval = 0;
localnotification.hasAction=YES;
[[UIApplication sharedApplication]scheduleLocalNotification:localnotification];
}
else
{
[[[UIAlertView alloc]initWithTitle:@"message" message:@"Enter into region." delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok ", nil] show];
}
});
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
dispatch_async(dispatch_get_main_queue(), ^{
if ([[UIApplication sharedApplication] applicationState]==UIApplicationStateBackground || [[UIApplication sharedApplication] applicationState]==UIApplicationStateInactive)
{
UILocalNotification *localnotificationExit = [[UILocalNotification alloc]init];
localnotificationExit.fireDate=[NSDate dateWithTimeIntervalSinceNow:1];
localnotificationExit.alertBody=@"You are exit from region.";
NSLog(@"Exit from region.");
localnotificationExit.timeZone=[NSTimeZone defaultTimeZone];
localnotificationExit.repeatInterval = 0;
localnotificationExit.hasAction=YES;
[[UIApplication sharedApplication]scheduleLocalNotification:localnotificationExit];
}
else
{
[[[UIAlertView alloc]initWithTitle:@"message" message:@"Exit from region." delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok ", nil] show];
}
});
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"didFailWithError: %@", error);
[[[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
}
This things are to manage the region monitoring.
Now my view controller are adding the regions for monitoring.
-(void)AddRegionsInGeoFence
{
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
//----1
CLLocationCoordinate2D centerCoordinate1 = CLLocationCoordinate2DMake(23.046518, 72.543337);
CLCircularRegion *region1 =[[CLCircularRegion alloc] initWithCenter:centerCoordinate1 radius:200 identifier:@"Location First"];
NSLog(@"%@",[region1 description]);
region1.notifyOnEntry=YES;
region1.notifyOnExit=YES;
if (![standardDefaults boolForKey:@"EnterRegion"])
{
[[AppDelegate sharedDelegate].locationManager startMonitoringForRegion:region1];
NSLog(@"Started Monitoring- %@", [region1 description]);
}
[self.mapview setShowsUserLocation:YES];
[self.mapview setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
//----2
CLLocationCoordinate2D centercoordinate2=CLLocationCoordinate2DMake(23.064381, 72.531181);
CLCircularRegion *region2=[[CLCircularRegion alloc]initWithCenter:centercoordinate2 radius:200 identifier:@"Location Second"];
NSLog(@"%@",[region2 description]);
region2.notifyOnEntry=YES;
region2.notifyOnExit=YES;
if (![standardDefaults boolForKey:@"EnterRegion"])
{
[[AppDelegate sharedDelegate].locationManager startMonitoringForRegion:region2];
NSLog(@"Started Monitoring- %@", [region2 description]);
}
//----3
CLLocationCoordinate2D centercoordinate3=CLLocationCoordinate2DMake(23.083583,72.546441);
CLCircularRegion *region3=[[CLCircularRegion alloc]initWithCenter:centercoordinate3 radius:200 identifier:@"Location Third"];
NSLog(@"%@",[region3 description]);
region3.notifyOnEntry=YES;
region3.notifyOnExit=YES;
if (![standardDefaults boolForKey:@"EnterRegion"])
{
[[AppDelegate sharedDelegate].locationManager startMonitoringForRegion:region3];
NSLog(@"Started Monitoring- %@", [region3 description]);
}
//4
CLLocationCoordinate2D centercoordinate4=CLLocationCoordinate2DMake(23.122255, 72.584499);
CLCircularRegion *region4=[[CLCircularRegion alloc]initWithCenter:centercoordinate4 radius:500 identifier:@"Location Fourth"];
NSLog(@"%@",[region4 description]);
region4.notifyOnEntry=YES;
region4.notifyOnExit=YES;
if (![standardDefaults boolForKey:@"EnterRegion"])
{
[[AppDelegate sharedDelegate].locationManager startMonitoringForRegion:region4];
NSLog(@"Started Monitoring- %@", [region4 description]);
[standardDefaults setBool:YES forKey:@"EnterRegion"];
[standardDefaults synchronize];
}
}
My Problem is region monitoring methods are called multiple times even if I am not moving in side the region itself. Everything else is working fine, Accuracy buffer is around 50-80 meters
that is fine for me.
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
Also if I am turning off Wi-Fi then it's calling up these methods back to back saying exit from region and enter in to region. As far as I know GPS accuracy is depends on Wi-Fi.
Any help would be highly appreciated.