地理围栏多次调用区域监视方法 [英] Region Monitoring method getting called multiple times in Geo-Fencing

查看:70
本文介绍了地理围栏多次调用区域监视方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了多个地理围栏来监视区域进入/退出事件。

I have created multiple geo-fence to monitor region entry/exit events.

我创建了位置管理器 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];
        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];
    }
}

我的问题是区域监视方法甚至被多次调用如果我不在区域本身旁边移动。其他一切工作正常,准确度缓冲 50-80米左右,对我来说很好。

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

此外,如果我要关闭Wi -Fi然后依次调用这些方法,说退出区域并进入区域。据我所知,GPS精度取决于Wi-Fi。

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.

任何帮助将不胜感激。

推荐答案

在修正Apple Bug的过程中,一种可能的解决方法是限制回调的速率。

a Possible workaround in the interim while the apple bug gets fixed is to rate limit the callback; thereby not acting on all the callbacks but limiting the rate at which the callbacks can get processed.

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

Callback execution portions that happen before the time period expires get ignored.

以下是示例代码,可以提供帮助,未经测试
速率限制为2秒。

Here is and example code that could assist, not tested: The rate is limited to 2 seconds.

-(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");
        }
    }
}

这篇关于地理围栏多次调用区域监视方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆