iOS9 中 CLLocationManager 中的 allowsBackgroundLocationUpdates

allowsBackgroundLocationUpdates in CLLocationManager in iOS9

我在 Xcode7(预发布)的应用程序中使用 CoreLocation 框架,我注意到有一个新添加的 属性 称为 allowsBackgroundLocationUpdatesCLLocationManager class.

这个 属性 与功能选项卡的后台模式中的位置更新之间有什么关系。它的默认值是多少?它会影响 iOS9 中的应用 运行 吗?

这个新的 属性 在 WWDC session "What's New in Core Location" 中有解释。

默认值是 NO 如果你 link 反对 iOS 9.

如果您的应用在后台使用位置信息(不显示蓝色状态栏),除了在 Info.plist 中设置后台模式功能外,您还必须将 allowsBackgroundLocationUpdates 设置为 YES .否则位置更新仅在前台传送。优点是您现在可以在同一个应用程序中拥有具有后台位置更新的位置管理器和 other 仅具有前台位置更新的位置管理器。您还可以将值重置为 NO 以更改行为。

文档对此非常清楚:

By default, this is NO for applications linked against iOS 9.0 or later, regardless of minimum deployment target.

With UIBackgroundModes set to include "location" in Info.plist, you must also set this property to YES at runtime whenever calling -startUpdatingLocation with the intent to continue in the background.

Setting this property to YES when UIBackgroundModes does not include "location" is a fatal error.

Resetting this property to NO is equivalent to omitting "location" from the UIBackgroundModes value. Access to location is still permitted whenever the application is running (ie not suspended), and has sufficient authorization (ie it has WhenInUse authorization and is in use, or it has Always authorization). However, the app will still be subject to the usual task suspension rules.

See -requestWhenInUseAuthorization and -requestAlwaysAuthorization for more details on possible authorization values.

如果您在 Xcode7(pre-released) 的应用程序中使用 CoreLocation 框架,您可能会注意到在 CLLocationManager class.

这个新的 属性 在 WWDC session "What's New in Core Location" 中有解释。

默认值是 NO 如果你 link 反对 iOS 9.

如果您的应用程序在后台使用位置信息(不显示蓝色状态栏),除了在 Info.plist 中设置后台模式功能外,您还必须将 allowsBackgroundLocationUpdates 设置为 YES .否则位置更新仅在前台传送。优点是您现在可以在同一应用程序中拥有具有后台位置更新的位置管理器和仅具有前台位置更新的其他位置管理器。您还可以将值重置为 NO 以更改行为。

文档对此非常清楚:

By default, this is NO for applications linked against iOS 9.0 or later, regardless of minimum deployment target.

With UIBackgroundModes set to include "location" in Info.plist, you must also set this property to YES at runtime whenever calling -startUpdatingLocation with the intent to continue in the background.

Setting this property to YES when UIBackgroundModes does not include "location" is a fatal error.

Resetting this property to NO is equivalent to omitting "location" from the UIBackgroundModes value. Access to location is still permitted whenever the application is running (ie not suspended), and has sufficient authorization (ie it has WhenInUse authorization and is in use, or it has Always authorization). However, the app will still be subject to the usual task suspension rules.

See -requestWhenInUseAuthorization and -requestAlwaysAuthorization for more details on possible authorization values.

设置Info.plist喜欢:

Info.plist 配置的语法如下所示:

<key>NSLocationAlwaysUsageDescription</key>
<string>I want to get your location Information in background</string>

<key>UIBackgroundModes</key>
<array>
    <string>location</string>
</array>

或者调出应用目标的“功能”选项卡。


(来源:raywenderlich.com

像这样使用:

_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
[_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) {
    [_locationManager requestAlwaysAuthorization];
}
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
    _locationManager.allowsBackgroundLocationUpdates = YES;
}
[_locationManager startUpdatingLocation];

我写一个DemoHere (Demo2)

好吧,我还在使用 xCode 6,因为 7 beta 总是在模拟器上崩溃,我有这个问题,虽然我什至 link 反对 iOS9 !而且我无法设置此 属性,因为它在 iOS8 中不存在!哦苹果,折磨什么时候结束?!

我通过执行此延迟绑定调用将其更改为此 xCode6 兼容版本:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0) {

            BOOL yes = YES;

            NSMethodSignature* signature = [[CLLocationManager class] instanceMethodSignatureForSelector: @selector( setAllowsBackgroundLocationUpdates: )];
            NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: signature];
            [invocation setTarget: locationManager];
            [invocation setSelector: @selector( setAllowsBackgroundLocationUpdates: ) ];
            [invocation setArgument: &yes atIndex: 2];
            [invocation invoke];
        }

已确认在 iOS8(不执行任何操作)和 iOS9 beta 6(正确调用方法)上工作。

Here是很多方法的总结,从iOS8更新到iOS9

应该为您正在使用的每个框架搜索许多 API 和代码。所以在General framework中搜索,然后找到这些方法来更新折旧方法。

我在 iOS 9.0.x 的后台模式下遇到了相同的位置服务,我按照此 post 中的建议通过添加以下代码修复了它

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
    _locationManager.allowsBackgroundLocationUpdates = YES;
}

然而它在iOS 9.1 中不起作用,有人遇到同样的问题吗??? 如果是这样,请帮忙。谢谢

{
NSArray* backgroundModes  = [NSBundle MainBundle].infoDictionary[@"UIBackgroundModes"];

     if(backgroundModes && [backgroundModes containsObject:@"location"]) {
         if([manager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
             // We now have iOS9 and the right capabilities to set this:
             [manager setAllowsBackgroundLocationUpdates:YES];
         }
     }
}