CLLocationManager仅在安装后第一次运行应用程序时监视区域
我有一个iOS应用程序,它是一个选项卡式应用程序,带有3个视图控制器,所有这些控件都需要知道手机何时进入特定的地理区域。
I have an iOS app which is a tabbed application, with 3 view controllers, all of which need to know when the phone enters specific geographical regions.
我们监视的区域是在运行时通过Web界面提供的,因此我们需要定期清除CLLocationManager监视的区域并添加新区域。 CLLocationManager对象是单例类的成员变量,该类也管理与Web服务器的连接。
The regions which we monitor for are supplied at run time over a web interface, so we need to periodically clear the regions that the CLLocationManager is monitoring for and add new ones. The CLLocationManager object is a member variable of a singleton class which manages the connection with the web server as well.
我遇到的问题是,在首次安装该应用程序时,区域监视工作正常。但是,我第一次尝试在之后之后运行它时,区域监视无效。
The problem that I have is that when the application is first installed, the region monitoring works fine. But the first time I try to run it after that first time, the region monitoring does not work.
我可以在实际的手机和 iOS模拟器上看到它。
I can see this on both the actual handset and the iOS simulator.
从服务器收到包含区域详细信息的消息后,我们运行以下代码:
On receipt of the mesasge from the server which contains the region details, we run the following code:
-(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文件时,它再次起作用,但是从第二次起,它不再起作用。
I have tried calling [locationmanager stopUpdatingLocation] in various places, in particular in various places in the AppDelegate.m file (applicationWilLResignActive, applicationDidEnterBackground, applicationWillTerminate), but none of them seem to help. Either way, when I build my application and add a GPX file to simulate locations, the simulator correctly picks up the regions being sent by the web interface. The second time I run the program, the regions are not picked up. When I reload the GPX file, it works again, but from the second time onwards, it doens't work any more.
根据API文档,CLLocationManager保持甚至在终止时也会记录区域的记录(这就是为什么我清除我们要监视的区域的原因),但是我的猜测是,初始化例程对于应用程序首次运行是好的,但是调用了不应从中调用的内容第二次起。另外,清除过程似乎并不总是起作用(NSLog语句通常显示CLLocationManager清除到0个区域,但并非总是如此)。
According to the API documentation, the CLLocationManager keeps a record of regions even on termination (which is why I clear down the regions which we monitor for), but my guess is that my initialisation routine is good for the first time the app runs, but calls things that shouldn't be called from the second time onwards. Also, the clearing down process doesn't always seem to work (the NSLog statement often shows the CLLocationManager clearing down to 0 regions, but not always).
任何想法
所以让我们清理一下
使用区域监视时,您不需要调用 startUpdatingLocation
和 stopUpdatingLocation
。那些激活标准位置跟踪,将消息发送到委托回调 locationManager:didUpdateLocations:
。区域跟踪应用程序实现了这些委托回调:
You dont need to call startUpdatingLocation
and stopUpdatingLocation
when using region monitoring. Those activate the standard location tracking sending messages to the delegate callback locationManager:didUpdateLocations:
. Region tracking apps implement these delegate callbacks:
– locationManager:didEnterRegion:
– locationManager:didExitRegion:
在这种方法中,定位服务也极有可能被禁用,因此您应该确保不可能从后台线程中删除 locationManager。因此,我们不需要再次检查它们。
Also its very unlikely that location services will become disabled in the course of this method and you should make sure its not possible to get rid of the 'locationManager' from a background thread. Therefore we dont need to check them twice.
当您进行区域监视时,最好确保使用 +(BOOL)进行区域监视regionMonitoringAvailable
。同样最好在某些时候使用 +(CLAuthorizationStatus)authorizationStatus
检查位置权限并做出适当反应。
As you are region monitoring its best to make sure you have region monitoring available with + (BOOL)regionMonitoringAvailable
. Also best to check the location permissions with + (CLAuthorizationStatus)authorizationStatus
at some point and react appropriately.
根据此博客文章,看来您还需要具有
As per this blog post it seems you also need to have
UIBackgroundModes :{location}
UIRequiredDeviceCapabilities: {location-services}
在您的应用程序info.plist中,所有这些都可以正常工作。
in your apps info.plist for this all to work correctly.
如果有更多有关失败模式的信息,我可以返回一些更具体的建议:)
If you have more information about the mode of failure i can come back with some more specific advice :)