CLLocationManager仅在安装后第一次运行应用程序时监视区域

时间:2013-08-27 12:56:42

标签: iphone ios core-location cllocationmanager

我有一个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个区域,但并非总是如此)。

为什么这不起作用?

1 个答案:

答案 0 :(得分:3)

所以让我们清理一下

使用区域监控时,您无需致电startUpdatingLocationstopUpdatingLocation。这些激活标准位置跟踪向委托回调locationManager:didUpdateLocations:发送消息。区域跟踪应用程序实现这些委托回调:

– locationManager:didEnterRegion:
– locationManager:didExitRegion:

此方法过程中定位服务也不太可能被禁用,你应该确保它不可能从后台线程中删除'locationManager'。因此,我们不需要检查它们两次。

由于您正在监控区域,以确保您可以使用+ (BOOL)regionMonitoringAvailable进行区域监控。最好还是在某个时候使用+ (CLAuthorizationStatus)authorizationStatus检查位置权限并做出适当的反应。

根据this blog post,您似乎还需要

UIBackgroundModes :{location}
UIRequiredDeviceCapabilities: {location-services}

在你的应用程序info.plist中,这一切都能正常工作。

如果您有关于失败模式的更多信息,我可以提出一些更具体的建议:)