区域在Geo-Fencing中多次调用的监控方法

问题描述:

我已经创建了多个地理围栏来监控区域进入/退出事件。区域在Geo-Fencing中多次调用的监控方法

我在AppDelegate.h文件中创建了一个位置管理器

@interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate> 

@property (strong, nonatomic) UIWindow *window; 

@property(nonatomic,retain)CLLocationManager *locationManager; 
@property(nonatomic,retain)CLLocation *currentLocation; 

+(AppDelegate *)sharedDelegate; 

AppDelegate.m文件

- (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]; 
     [email protected]"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]; 
     [email protected]"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]; 
} 

这东西是管理区域的监测。

现在我的视图控制器正在添加监视区域。

-(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]; 
    } 
} 

我的问题是区域监视方法被称为多次,即使我不移动区域本身。其他一切工作正常,准确性缓冲区50-80 meters这对我来说很好。

-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region 
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region 

此外,如果我关闭Wi-Fi,那么它会调用这些方法来回退出区域并输入到区域。据我所知,GPS的准确性取决于Wi-Fi。

任何帮助将不胜感激。

+1

我的代码中也有同样的问题。在我还在进入地理围栏时,区域监控方法会多次调用。这是[我的代码](http://*.com/questions/36719286/geofence-methods-region-monitoring-not-getting-called-while-updating-locations) – Merry

+0

@Merry是的,我已经通过这个链接,但你的问题是不同的。矿井代码多次调用,甚至没有调用。 –

+0

是的,你是对的我的问题标题与不调用任何委托方法有关,但现在输入和退出方法被成功调用,但在用户已经在区域内时调用多次。它显示多次**进入或退出**通知。 – Merry

a苹果错误得到修复的临时可能的解决方法是限制回调;从而不对所有的回调起作用,但限制了回调可以处理的速度。

在时间段过期之前发生的回调执行部分被忽略。

这是和示例代码,可以帮助,未测试: 速率限制为2秒。

-(void)methodRateLimit { 

    @synchronized(self) { 
     // rate limit begin 
     static NSDate *lastTimeExit = nil; 

     if (!lastTimeExit) { 
      lastTimeExit = [NSDate distantPast]; // way back in time 
     } 

     NSDate *now = [NSDate date]; 
     if ([now timeIntervalSinceDate:lastTimeExit] > 2) { 
      // do work here 
      NSLog(@"Executing"); 
      lastTimeExit = now; 
     } else { 
      NSLog(@"Limiting"); 
     } 
    } 
}