我已经对iOS进行了2个月的区域监测。最近,我们发现了一个小故障,在一定半径(约4.7公里或4700米)范围内的所有区域同时触发。设备的当前位置甚至不接近任何区域。我不知道是什么引发了这一事件。我已经搜索了StackOverFlow,苹果开发者论坛等,我没有发现任何类似的问题,我所面临的。
在我正在开发的应用程序中,我们正在监测城市内的8个地区(吉隆坡)。有一次,我的同事发现他的手机同时触发了4个区域的通知。下面是显示他的位置的地图,所有被监控的区域,触发4个区域通知的潜在半径。

触发通知的屏幕截图

这里是我的位置管理器的代码:-
CLLocationManager *locationManager = [LocationTracker sharedLocationManager];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
locationManager.distanceFilter = kCLDistanceFilterNone;,这是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];
}
}注意:这个问题并不是每次都会发生,它只是偶尔发生一次。4700米是我在分析了4个触发区域的位置后得出的半径。我不确定这是我的代码、iOS上的一个小问题,还是我的国家的本地电信有问题。在这个应用程序的最新版本中,我正在将distanceFiter调整为10,我们现在正在测试它,看它是否能解决这个问题。
//locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.distanceFilter = 10;方法didEnterRegion从来不返回用户的位置,我不能过滤出潜在的坏位置与大半径,如我上面展示的例子。我能做些什么来解决这个问题?
任何开发人员面临类似的问题,请站出来,并分享您的经验和解决方案,以解决这个问题(如果有)。谢谢。
发布于 2014-05-13 13:56:03
我找到了解决这个奇怪的虫子的方法。我们已经测试了超过一个星期,到目前为止,我们还没有看到同样的错误。以下是解决办法:
-(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];
}
}
}我使用containsCoordinate:方法使用CLLocation * lastLocation = [manager location];从设备获取最新位置,并使用此坐标查看是否位于触发区域内。如果它在内部,那么只有本地通知才会触发。
有关此bug的详细说明和修复方法,您可以访问:iOS区域监控和位置管理器
发布于 2015-12-15 12:04:42
这里 是一种完整的工作解决方案/修复iOS地理围栏故障!
它既解决了在网络交换机上接收错误的多个事件的问题,比如wifi到移动数据,又副了versa..also,它用这种逻辑/修复给出了准确的结果/通知。
基本上,LocationManager应该被看作是单例,而distanceFilter应该是kCLDistanceFilterNone,desiredAccuracy应该是kCLLocationAccuracyBestForNavigation (我们认为这是为了获得最好的精度,因为我们需要对位置的真实背景监测非常准确,以便实时向用户发送地理信息输入通知)
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
CLLocation * lastLocation = [manager location];
BOOL doesItContainMyPoint;
if(lastLocation==nil)
doesItContainMyPoint = NO;
else{
CLLocationCoordinate2D theLocationCoordinate = lastLocation.coordinate;
CLCircularRegion * theRegion = (CLCircularRegion*)region;
//we need to take new instance of given region for which the iOS triggers entry event..Adding 50.0 meters is needed just to make sure that containsCoordinate method of CLCircularRegion works well.Because there is lag/difference measured in our real time field testing that brought us to this conclusion and it works like a charm.If we do not add this 50.0 meters in the fence for which we are getting this event then there is a chance that containsCoordinate might miss the recent point/coordinate to consider in given region...
CLCircularRegion * theCircularRegion = [[CLCircularRegion alloc]initWithCenter:theRegion.center radius:theRegion.radius+50.0 identifier:theRegion.identifier];
doesItContainMyPoint = [theCircularRegion containsCoordinate:theLocationCoordinate];
}
if(doesItContainMyPoint){
NSLog(@"ItContainMyPoint");
//trigger local notification...
}else{
NSLog(@"ItDoesNotContainMyPoint");
//do not trigger local notification...because it is triggered due to switching network(wifi to mobile data and vice versa) Currently user is not at all in the region for which we are getting event of entry
return;
}
}发布于 2015-06-09 10:37:04
这是一个老生常谈的问题,但让我分享一下我在地区监控方面关于不准确的didExit didEnterRegion调用的经验:
有一点要注意的是,如果你关闭了Wifi设备,那么iOS设备上的地理信息的可靠性就会大大恶化。
在询问器的情况下,您不应该只检查要调试的最后一个位置的.coordinate,还应该检查CLLocation的.horizontalAccuracy。如果无线网络和全球定位系统被关闭,可能会显示出非常低的精确度(可能很大的区域)。在你也运行GPS定位跟踪的情况下,接受的答案实际上是一个很好的答案。如果不是,.horizontalAccuracy可能是一个非常大的数字。地区监测似乎(在我的经验)听GPS更新,所以你不能提高其可靠性的方式。但是启用WiFi可以。在一个城市里。
没有Wifi和GPS技巧,像公认的答案使用,所有的设备只有手机塔的位置。我已经发现,如果所有的设备都必须得到它的位置,didExitRegion和didEnterRegion可能是不可靠的,那就是蜂窝塔。这是因为手机塔的定位精度当然比无线网络低得多。在这种情况下,低精度(大的可能区域)可能意味着它在任何四个区域的提问者。对于单个区域,它甚至可能被多次调用,因为它可能突然认为(基于蜂窝塔)它在一公里之外,然后意识到它不是,这可能导致didEnterRegion被多次调用。
didExitRegion也是如此。如果准确度真的很低,系统无法确定您离开该区域直到几公里之外(这是评论者的问题之一)。
因此,如果你不确定你的用户在使用你的应用程序时总是打开wifi (你不能在iOS上检查或保证),确保你不会让区域太小,或者使用全球定位系统([locationManager startUpdatingLocation])接受的答案来确保你真的在那个区域。在这种情况下,还要检查位置是否准确,是否足够年轻。类似于:
CLLocation * lastLocation = [manager location];
NSTimeInterval locationAge = -[lastLocation.timestamp timeIntervalSinceNow];
if (lastLocation != nil && locationAge < MAX_AGE && self.currentLocation.horizontalAccuracy <= MAX_ACCURACY) {
CLLocationCoordinate2D theLocationCoordinate = lastLocation.coordinate;
CLCircularRegion * theRegion = (CLCircularRegion*)region;
doesItContainMyPoint = [theRegion containsCoordinate:theLocationCoordinate];
}但是,如果有任何方法可以说服用户在使用该应用程序时始终启用Wifi,请做!它使它更加可靠。
https://stackoverflow.com/questions/23439913
复制相似问题