我正在尝试测试区域监控,因为我正在获得这样的当前位置:
- (void)startLocationTracking
{
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
// Start location manager
if ([CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized) {
locationManager = [LocationTracker sharedLocationManager];
locationManager.delegate = self;
[locationManager startMonitoringSignificantLocationChanges];
}
}
跟踪区域监控的第一个位置,如下所示:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:manager.location.coordinate radius:300 identifier:@"first location initializer"];
NSLog(@"0: %@", manager.location);
NSLog(@"1: %@", region);
[manager startMonitoringForRegion:region];
NSLog(@"[locationManager startMonitoringForRegion:%@];", region);
});
}
然后在当前区域的每个出口处,我都在监视新位置:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(@"%s, %@", __PRETTY_FUNCTION__, region);
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
NSLog(@"%s, %@", __PRETTY_FUNCTION__, region);
NSArray *allRegions = manager.monitoredRegions.allObjects;
if (allRegions.count > 0) {
for (CLRegion *reg in allRegions) {
[manager stopMonitoringForRegion:reg];
}
}
CLLocationCoordinate2D cord = CLLocationCoordinate2DMake(manager.location.coordinate.latitude, manager.location.coordinate.longitude);
CLRegion *regionNew = [[CLRegion alloc] initCircularRegionWithCenter:cord radius:300 identifier:@"new region"];
NSLog(@"region: %@", region);
NSLog(@"regionNew: %@", regionNew);
[manager startMonitoringForRegion:regionNew];
}
我会解释我期望发生的事情:
这不会发生。
我哪里错了?
我尝试使用'Freeway Drive'模拟器。
更新
经过测试和工作,由于地理围栏中的Apple漏洞,应用程序仅支持7.1+,非常糟糕,但我没有其他想法。
答案 0 :(得分:11)
我认为实施区域监控的方式可能会导致一些问题。
原因如下: -
在startLocationTracking
方法中,您的locationManager
是一个本地对象,不会延伸到该方法的生命周期。这也意味着每次调用startLocationTracking
时,都会有一个新的locationManager
对象被分配一个新的内存块。
要解决此问题:您应该在应用程序的整个生命周期中使用共享locationManager
的单例 locationManager
。
我认为你不应该在委托方法startMonitoringForRegion
内-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:
。原因是,如果再次调用startLocationTracking
一次,则会有多个locationManager。多个locationManagers可以监视可能导致多个通知的同一区域。
致电[manager startMonitoringForRegion:region];
后,我们不会立即监控该地区。如果您不相信我,请尝试以下代码: -
[locationManager startMonitoringForRegion:region];
NSLog(@"%@",locationManager.monitoredRegions);
您会发现您刚刚监控的区域不在locationManager.monitoredRegions
内。由于这是在iOS级别上处理的,因此,我认为可能需要几分钟时间才能对该区域进行监控。
您还应该了解iOS中区域监控的其他限制: -
应用最多可以一次注册20个地区。为了报告 区域变化及时,区域监测服务 需要网络连接。
在iOS 6中,半径在1到400米之间的区域效果更好 在iPhone 4S或更高版本的设备上。 (在iOS 5中,具有半径的区域 在iPhone 4S和更高版本的设备上,1到150米之间的效果会更好。) 在这些设备上,应用程序可以期望接收适当的区域 在3到5分钟内输入或区域退出通知 平均,如果不是更快。
注意:只要设备移动500,应用就会收到通知 距其先前通知的米或更多。不应该期待 通知频率高于每五分钟一次。如果 设备能够从网络中检索位置管理器的数据 更有可能及时发送通知。
我不知道您的应用是什么,我相信您应该重新设计应用流程。您应该尝试监视委托方法之外的区域。
有关 Singleton LocationManager 的详细信息,您可以查看以下答案:Background Location Services not working in iOS 7。 GitHub上有一个包含 Singleton LocationManager类的完整项目,我将其命名为 LocationTracker 。
您可能还想查看我在一个月前发现的iOS 7中的区域监控故障(解决故障的解决方法):Region Monitoring Glitch on iOS 7 - Multiple Notifications at the same time
答案 1 :(得分:0)
对于代表方法(didEnterRegion和didExitRegion)没有被调用的最满意的答案是,apple docs说你会在进入或退出后3到5分钟得到通知,但在实际测试中我发现的是你必须等待大约7到8分钟。
我测试了10到15次,我的区域半径大约是80米。我正在挠头看看出了什么问题。我打开了模拟器并打开了位置跟踪(使用gpx文件进行位置模拟)。 8分钟后,调用了ExitRegion。
此外,如果您想在后台执行此操作,则必须在目标上启用后台模式。