【问题标题】:CLLocationManager only monitors regions the first time the app is run after installCLLocationManager 仅在安装后第一次运行应用程序时监控区域
【发布时间】:2013-08-30 05:45:38
【问题描述】:

我有一个 iOS 应用程序,它是一个选项卡式应用程序,具有 3 个视图控制器,所有这些都需要知道手机何时进入特定地理区域。

我们监控的区域是在运行时通过 Web 界面提供的,因此我们需要定期清除 CLLocationManager 正在监控的区域并添加新的区域。 CLLocationManager 对象是一个单例类的成员变量,它也管理与 Web 服务器的连接。

我遇到的问题是,首次安装应用程序时,区域监控工作正常。但是我第一次尝试运行它第一次之后,区域监控不起作用。

我可以在实际的手机 iOS 模拟器上看到这一点。

从服务器收到包含区域详细信息的消息后,我们运行以下代码:

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

任何想法为什么这不起作用?

【问题讨论】:

    标签: iphone ios core-location cllocationmanager


    【解决方案1】:

    所以让我们稍微清理一下

    使用区域监控时不需要调用startUpdatingLocationstopUpdatingLocation。那些激活标准位置跟踪发送消息到委托回调locationManager:didUpdateLocations:。区域跟踪应用实现这些委托回调:

    – locationManager:didEnterRegion:
    – locationManager:didExitRegion:
    

    此外,位置服务不太可能在此方法的过程中被禁用,您应确保无法从后台线程中删除“locationManager”。因此我们不需要检查它们两次。

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

    根据this blog post 看来你也需要拥有

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

    在您的应用程序 info.plist 中让这一切正常工作。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多