我一直不知道如何处理这种情况:当调用startMonitoringForRegion
时,手机已经在一个区域内。其他问题建议在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
是我自己写的,并且它工作正常,而对象包含的内容如纬度、经度和半径也都可以正常使用,因此这不是问题所在。
无论如何,上面代码的问题在于,如果用户在将区域添加到他们的设备时已经在该区域内(即完成了didEnterRegion
),则它确实可以工作。 然而,问题在于每当通过苹果文档的边界区域之一时,也会调用didDetermineState: forRegion:
方法:
每当区域发生边界转换时,位置管理器都会调用此方法。 它除了调用locationManager:didEnterRegion:和locationManager:didExitRegion:方法之外还调用此方法。 位置管理器还响应对其requestStateForRegion:方法的调用并调用此方法。
由于这个原因,每当进入一个区域时,didEnterRegion
会自动被调用,但随后didDetermineState: forRegion:
也会被自动调用,导致再次调用didEnterRegion
,结果导致区域被重复进入了两次,而我只想要它进入一次。怎样才能避免这种情况呢?
谢谢你的帮助。
解决方案
解决方法非常简单,只是我走了弯路。我必须选择使用两个方法didEnterRegion:
和didExitRegion
或者使用didDetermineState: forRegion
并创建自己的进入和退出区域的方法,两者都不应该使用。
所以我选择只使用didDetermineState: forRegion
方法,我的代码现在看起来像这样:
请注意,使用这种方法,如果不在区域内,则会为该区域调用退出区域的方法。 如果像我一样,您只希望在进入区域后才发生退出,您将需要某种检查区域是否已经进入的方法(我自己使用core data,因为我已经在使用它来存储区域的其他方面)。
- (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
}