我一直无法弄清楚如何处理电话在startMonitoringForRegion
被呼叫时已经在一个区域内的情况?其他问题建议在 thisrequestStateForRegion
内部调用didStartMonitoringForRegion
然后调用方法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 long 和 radius 之类的东西,而且一切正常,所以这不是这里的问题。
无论如何,上述代码的问题在于,如果用户在将区域添加到他们的设备时已经在该区域内(即 didEnterRegion 完成),则它确实有效。然而问题是,didDetermineState: forRegion:
每次根据苹果文档跨越边界区域之一时,也会调用该方法:
只要有区域的边界转换,位置管理器就会调用此方法。除了调用 locationManager:didEnterRegion: 和 locationManager:didExitRegion: 方法之外,它还调用此方法。位置管理器还调用此方法以响应对其 requestStateForRegion: 方法的调用,该方法异步运行。
现在正因为如此,每次输入一个区域时,didEnterRegion
都会自动调用它,但随后会再次调用它,因为didDetermineState: forRegion:
根据苹果文档也会自动调用它,这会导致didEnterRegion
再次调用,所以当我只希望它是时,该区域被输入两次输入一次。我怎样才能避免这种情况?
谢谢你的帮助。
解决方案
解决方案真的很简单,我只是以错误的方式去做。我不得不选择使用这两种方法didEnterRegion:
,didExitRegion
或者使用didDetermineState: forRegion
并创建我自己的方法来进入和退出该区域,两者都不应该使用。
所以我选择只使用该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 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
}