我有一个iOS应用程序,它是一个标签式应用程序,有3个视图控制器,所有这些都需要知道手机什么时候进入特定的地理区域。
我们监控的区域是在运行时通过Web界面提供的,因此我们需要定期清除CLLocationManager监控的区域并添加新区域。 CLLocationManager对象是singleton类的成员变量,它也管理与Web服务器的连接。
我遇到的问题是,首次安装应用程序时,区域监控工作正常。但是第一次尝试在第一次之后运行它时,区域监控不起作用。
我可以在iOS模拟器的实际手机和上看到这一点。
在收到包含区域详细信息的服务器的mesasge后,我们运行以下代码:
-(void) initialiseLocationManager:(NSArray*)geofences
{
if(![CLLocationManager locationServicesEnabled])
{
NSLog(@"Error - Location services not enabled");
return;
}
if(self.locationManager == nil)
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
}
else
{
[self.locationManager stopUpdatingLocation];
}
for(CLRegion *geofence in self.locationManager.monitoredRegions)
{
//Remove old geogate data
[self.locationManager stopMonitoringForRegion:geofence];
}
NSLog(@"Number of regions after cleanup of old regions: %d", self.locationManager.monitoredRegions.count);
if(self.locationManager == nil)
{
[NSException raise:@"Location manager not initialised" format:@"You must intitialise the location manager first."];
}
if(![CLLocationManager regionMonitoringAvailable])
{
NSLog(@"This application requires region monitoring features which are unavailable on this device");
return;
}
for(CLRegion *geofence in geofences)
{
//Add new geogate data
[self.locationManager startMonitoringForRegion:geofence];
NSLog(@"Number of regions during addition of new regions: %d", self.locationManager.monitoredRegions.count);
}
NSLog(@"Number of regions at end of initialiseRegionMonitoring function: %d", self.locationManager.monitoredRegions.count);
[locationManager startUpdatingLocation];
}
我尝试在各个地方调用[locationmanager stopUpdatingLocation],特别是在AppDelegate.m文件中的各个地方(applicationWilLResignActive,applicationDidEnterBackground,applicationWillTerminate),但它们似乎都没有帮助。无论哪种方式,当我构建我的应用程序并添加GPX文件来模拟位置时,模拟器会正确地选取Web界面发送的区域。第二次运行程序时,区域没有被选中。当我重新加载GPX文件时,它再次起作用,但从第二次开始,它再也无法工作了。
根据API文档,CLLocationManager即使在终止时也会保留区域记录(这就是为什么我要清除我们监视的区域),但我的猜测是我的初始化例程第一次应用程序是好的运行,但调用第二次不应该调用的东西。此外,清除过程似乎并不总是有效(NSLog语句通常显示CLLocationManager清除为0个区域,但并非总是如此)。
为什么这不起作用?
答案 0 :(得分:3)
所以让我们清理一下
使用区域监控时,您无需致电startUpdatingLocation
和stopUpdatingLocation
。这些激活标准位置跟踪向委托回调locationManager:didUpdateLocations:
发送消息。区域跟踪应用程序实现这些委托回调:
– locationManager:didEnterRegion:
– locationManager:didExitRegion:
此方法过程中定位服务也不太可能被禁用,你应该确保它不可能从后台线程中删除'locationManager'。因此,我们不需要检查它们两次。
由于您正在监控区域,以确保您可以使用+ (BOOL)regionMonitoringAvailable
进行区域监控。最好还是在某个时候使用+ (CLAuthorizationStatus)authorizationStatus
检查位置权限并做出适当的反应。
根据this blog post,您似乎还需要
UIBackgroundModes :{location}
UIRequiredDeviceCapabilities: {location-services}
在你的应用程序info.plist中,这一切都能正常工作。
如果您有关于失败模式的更多信息,我可以提出一些更具体的建议:)