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属性可能会给你陈旧的或非常不准确的阅读。