iOS Geofence,监控开始时如何处理内部区域?
我一直无法解决如何处理手机已经在区域内的情况下startMonitoringForRegion
被称为? 其他问题已经build议在didStartMonitoringForRegion
调用requestStateForRegion
然后调用方法didDetermineState: forRegion:
所以代码看起来像这样:
- (void)viewDidLoad { //location manager set up etc... for (Object *object in allObjects){ CLRegion *region = [self geofenceRegion:object]; [locationManager startMonitoringForRegion:region]; } } - (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region { [self.locationManager requestStateForRegion:region]; [self.locationManager performSelector:@selector(requestStateForRegion:) withObject:region afterDelay:5]; } - (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region { if (state == CLRegionStateInside){ [self locationManager:locationManager didEnterRegion:region]; } }
现在很明显geofenceRegion方法是我自己的,并且工作正常,对象包含像lat和radius这样的东西,并且一切正常,所以这不是问题。
无论如何,上述代码的问题在于,如果用户已经在该区域内添加了该区域(例如didEnterRegion),该用户就已经可以工作了。 然而,问题是方法didDetermineState: forRegion:
也被称为每当一个边界区域是根据苹果文档交叉:
位置pipe理器在区域出现边界转换时调用此方法。 除了调用locationManager:didEnterRegion:和locationManager:didExitRegion:方法外,它还调用此方法。 位置pipe理器还响应对其requestStateForRegion:方法的调用来调用此方法,该方法asynchronous运行。
现在每次input区域时didEnterRegion
自动调用didEnterRegion
但是之后会再次调用它,因为didDetermineState: forRegion:
也会根据apple文档自动调用,导致didEnterRegion
被再次调用,所以在input区域时会input两次我只希望它被input一次。 我怎样才能避免这一点?
谢谢你的帮助。
解
解决scheme真的很简单,我只是以错误的方式去做。 我不得不select使用2方法didEnterRegion:
和didExitRegion
或使用didDetermineState: forRegion
并创build我自己的方法进入和退出区域, 都不应该使用 。
所以我select只使用didDetermineState: forRegion
方法,现在我的代码如下所示:
请注意,使用这种方法,出口区域将被称为该地区,如果不是在里面,如果像我一样,只希望退出发生在input发生后,您将需要某种方法检查该区域是否已经进入(我自己使用核心数据,因为我已经使用它来存储区域的其他方面)。
- (void)viewDidLoad { //location manager set up etc... for (Object *object in allObjects){ CLRegion *region = [self geofenceRegion:object]; [locationManager startMonitoringForRegion:region]; } } - (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region { [self.locationManager performSelector:@selector(requestStateForRegion:) withObject:region afterDelay:5]; } - (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region { if (state == CLRegionStateInside){ [self enterGeofence:region]; } else if (state == CLRegionStateOutside){ [self exitGeofence:region]; } else if (state == CLRegionStateUnknown){ NSLog(@"Unknown state for geofence: %@", region); return; } } - (void)enterGeofence:(CLRegion *)geofence { //whatever is required when entered } - (void)exitGeofence:(CLRegion *)geofence { //whatever is required when exit }
只要不使用locationManager:didEnterRegion:完全可以作为locationManager:didDetermineState:forRegion:为您提供触发input代码所需的所有信息,顺便说一句,不应该是locationManager:didEnterRegion:,请使用您的自己的select器,这不是CLLocationManagerDelegate协议的一部分。
另一种方法是在开始监视区域时testing区域内的位置。 这个解决scheme并不是那么简单,因为你需要先调用startUpdatingLocation来更新当前位置,因为只是阅读locationManager的location属性可能会给你陈旧的或非常不准确的阅读。