1

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

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

4

1 回答 1

3

所以让我们稍微清理一下

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

– locationManager:didEnterRegion:
– locationManager:didExitRegion:

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

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

根据此博客文章,您似乎还需要拥有

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

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

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

于 2013-08-27T16:30:15.393 回答