区域监控iOS 7上的故障 - 同时发出多个通知

Ric*_*cky 5 objective-c core-location cllocationmanager ios ios7

我一直在iOS上开发区域监控大约2个月.最近我们发现了一个小故障,同时在一定半径范围内(约4.7KM或4700米)触发了所有区域.设备的当前位置甚至不靠近任何区域.我不确定是什么原因引发了这一事件.我搜索了StackOverFlow,Apple Developer论坛等,我没有发现任何与我面临的类似问题.

在我正在开发的应用程序中,我们正在监控城市内的8个区域(吉隆坡).有一次,我的同事发现他的手机同时触发了4个地区通知.下面是显示其位置,所有受监控区域,触发4区域通知的潜在半径的地图.

iOS区域监控

  • 绿色标记是接收通知时设备的位置.
  • 蓝色圆圈是设备的潜在半径(约4700米),其覆盖了将通知发送到设备的4个区域.
  • 红色圆圈是每个区域的半径.
  • 地图上还有其他2个区域从不发送通知(从不覆盖在蓝色圆圈下)

触发通知的屏幕截图:

iOS区域监控故障

这是我的位置管理器代码: -

CLLocationManager *locationManager = [LocationTracker sharedLocationManager];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
locationManager.distanceFilter = kCLDistanceFilterNone;
Run Code Online (Sandbox Code Playgroud)

这是我的didEnterRegion代码: -

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

NSString* message = [NSString stringWithFormat:@"Message"];        
UIApplicationState state = [[UIApplication sharedApplication] applicationState];

if (state == UIApplicationStateBackground || state == UIApplicationStateInactive)
{
   UILocalNotification *notification = [[UILocalNotification alloc] init];
   notification.fireDate = [NSDate date];
   NSTimeZone* timezone = [NSTimeZone defaultTimeZone];
   notification.timeZone = timezone;
   notification.alertBody = message;
   notification.alertAction = @"Show";
   notification.soundName = UILocalNotificationDefaultSoundName;
   [[UIApplication sharedApplication] scheduleLocalNotification:notification];
 }

}
Run Code Online (Sandbox Code Playgroud)

注意:这个问题不是每次都会发生,它只会偶尔发生一次.4700米是我在分析了4个触发区域的位置后得出的半径.我不确定这是否是我的代码上的故障,在iOS上或我国家的本地电信公司有问题.在最新版本的应用程序中,我将distanceFiter调整为10,我们正在测试它,看看是否能解决问题.

//locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.distanceFilter = 10;
Run Code Online (Sandbox Code Playgroud)

方法didEnterRegion永远不会返回用户的位置,我无法过滤掉具有大半径的潜在坏位置,就像上面显示的示例一样.我能做些什么来解决这个小故障?

任何面临类似问题的开发人员,请站出来分享您的经验和解决方案以解决此问题(如果有的话).谢谢.

Ric*_*cky 6

我找到了解决这个奇怪错误的方法.我们已经测试了超过1周,到目前为止我们还没有再看到相同的bug.这是解决方案: -

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

NSLog(@"didEnterRegion");
CLLocation * lastLocation = [manager location];

BOOL doesItContainMyPoint;

if(lastLocation==nil)
    doesItContainMyPoint = NO;
else{
    CLLocationCoordinate2D theLocationCoordinate = lastLocation.coordinate;
    CLCircularRegion * theRegion = (CLCircularRegion*)region;
    doesItContainMyPoint = [theRegion containsCoordinate:theLocationCoordinate];
}

if(doesItContainMyPoint){
    NSString* message = [NSString stringWithFormat:@"You are now in this region:%@",region.identifier];
    UIApplicationState state = [[UIApplication sharedApplication] applicationState];

    if (state == UIApplicationStateBackground || state == UIApplicationStateInactive)
       {
         UILocalNotification *notification = [[UILocalNotification alloc] init];
         notification.fireDate = [NSDate date];
         NSTimeZone* timezone = [NSTimeZone defaultTimeZone];
         notification.timeZone = timezone;
         notification.alertBody = message;
         notification.alertAction = @"Show";
         notification.soundName = UILocalNotificationDefaultSoundName;
         [[UIApplication sharedApplication] scheduleLocalNotification:notification];
        }
  }
}
Run Code Online (Sandbox Code Playgroud)

我用来CLLocation * lastLocation = [manager location];从设备获取最新位置,并使用此坐标查看它是否在containsCoordinate:方法的触发区域内.如果它在里面,那么只会触发本地通知.

有关此错误及其修复方法的详细说明,您可以访问:iOS Region Monitoring and Location Manager