我一直无法弄清楚如何处理手机已经在某个区域内的情况startMonitoringForRegion
叫做?其他问题建议致电requestStateForRegion
inside 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 方法是我自己的,它工作得很好,并且对象包含诸如经纬度和半径之类的东西,所有这些都工作得很好,所以这不是这里的问题。
无论如何,上述代码的问题在于,如果用户在将区域添加到设备时已经位于该区域内(即 didEnterRegion 已完成),那么它确实可以工作。然而问题是该方法didDetermineState: forRegion:
根据苹果文档,每次跨越其中一个边界区域时也会调用:
每当区域发生边界转换时,位置管理器都会调用此方法。除了调用 locationManager:didEnterRegion: 和 locationManager:didExitRegion: 方法之外,它还调用此方法。位置管理器还调用此方法来响应对其异步运行的 requestStateForRegion: 方法的调用。
现在正因为如此,每次进入一个区域时,didEnterRegion
被自动调用,但随后又被再次调用,因为didDetermineState: forRegion:
也会根据苹果文档自动调用,这会导致didEnterRegion
再次被调用,因此当我只想输入一次时,该区域被输入两次。我怎样才能避免这种情况?
感谢您的帮助。
SOLUTION
解决方案真的很简单,我只是以错误的方式进行。我必须选择使用这两种方法didEnterRegion:
and didExitRegion
or use 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
}