我正在使用locationManager:didStartMonitoringForRegion:
进行区域监控。有时回调包含错误的区域,即使CLLocationManager.monitoredRegions
中显示的右侧区域。
locationManager:didStartMonitoringForRegion:
消息:
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
NSLog(@"Started monitoring %@ region", region.identifier);
NSLog(@"Monitored regions: %@", self.locationManager.monitoredRegions);
}
这里是一个示例输出(经常/经过改变以保存地点)
2013-12-13 20:01:34.047 N[] Started monitoring Hamburg region
2013-12-13 20:01:34.048 N[] Monitored regions: {(
CLCircularRegion (identifier:'Hamburg', center:<+47.0,+8.1>, radius:1000.00m),
CLCircularRegion (identifier:'Zürich', center:<+47.0,+8.0>, radius:500.00m),
CLCircularRegion (identifier:'St.Gallen', center:<+47.0,+9.0>, radius:5000.00m)
)}
2013-12-13 20:01:42.070 N[] Started monitoring Hamburg region
2013-12-13 20:01:42.072 N[] Monitored regions: {(
CLCircularRegion (identifier:'Hamburg', center:<+47.0,+8.1>, radius:1000.00m),
CLCircularRegion (identifier:'Zürich', center:<+47.0,+8.0>, radius:500.00m),
CLCircularRegion (identifier:'St.Gallen', center:<+47.0,+9.0>, radius:5000.00m)
)}
2013-12-13 20:01:46.837 N[] Started monitoring Hamburg region
2013-12-13 20:01:46.839 N[] Monitored regions: {(
CLCircularRegion (identifier:'Hamburg', center:<+47.0,+8.1>, radius:1000.00m),
CLCircularRegion (identifier:'Zürich', center:<+47.0,+8.0>, radius:500.00m),
CLCircularRegion (identifier:'St.Gallen', center:<+47.0,+9.0>, radius:5000.00m)
)}
我开始在didUpdateLocations
进行监控,在我致电startMonitoringSignificantLocationChanges
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
NSLog(@"%s", __PRETTY_FUNCTION__);
[manager stopMonitoringSignificantLocationChanges];
if (locations && [locations count]){
CLLocation* position = [locations lastObject];
NSLog(@"New Location latitude: %f longitude %f", position.coordinate.latitude, position.coordinate.longitude);
//self.geofences.allValues is containing Hamburg,Zürich and St.Gallen
for(CLCircularRegion *geofence in self.geofences.allValues) {
if(![self.locationManager.monitoredRegions containsObject:geofence]){
[self.locationManager startMonitoringForRegion:geofence];
}
if([geofence containsCoordinate:[position coordinate]]){
[self locationManager:manager didEnterRegion:geofence];
}
}
}
}
didEnterRegion
为@synchronized
以保证原子性。
有什么想法吗?
答案 0 :(得分:0)
我无法理解为什么它会反复注册同一个区域。我的怀疑会导致我在那里放一些额外的NSLog调用以验证你的源代码,self.geofences的内容。我要做的另一件事是在那里放置一个中断来观察For循环中的值和条件。
我要检查的其他两件事:
if(![self.locationManager.monitoredRegions containsObject:geofence]){
获得了预期结果。 CLLocationManager中的对象不保证与您最初注册的对象相同。您应该使用isEqualToString测试正确的标识符。您可能会在书写时无意中替换您的地区。didEnterRegion
。在发布之间报告边界事件。即使应用程序被终止,它也应该在重新启动时自动处理。如果没有一个可以解释这个问题,我会看看你是如何以及何时开始/停止位置服务的。是否有可能每个调用都是didUpdateLocations方法的另一个迭代?
我希望第一次调用它时,在一个全新的会话中,monitoredRegions为空,因此您的过程按预期工作。我看到了后续位置更新可能出现的不可预测行为的原因。
我首先要完全改变你的for循环。
if (locations && locations.count) {
CLLocation* position = [locations lastObject];
NSSet *regionIdentifiers = [self.locationManager.monitoredRegions valueForKey:@"identifier"];
NSSet *regionsForMonitoring = [NSSet setWithArray:self.geofences.allValues];
NSSet *unMonitoredRegions = [regionsForMonitoring objectsPassingTest:^BOOL(id obj, BOOL *stop) {
CLCircularRegion *regionForTest = (CLCircularRegion *)obj;
if (![regionIdentifiers containsObject:regionForTest.identifier]) {
return YES;
} else {
return NO;
}
}];
for (CLCircularRegion *geofence in unMonitoredRegions) {
[self.locationManager startMonitoringForRegion:geofence];
// We'll check if we are in the new region as it was not previously monitored
if([geofence containsCoordinate:[position coordinate]]){
[self locationManager:manager didEnterRegion:geofence];
}
}
}