allowsBackgroundLocationUpdates in CLLocationManager in iOS9
Asked Answered
B

6

66

I'm using CoreLocation framework in my app in Xcode7(pre-released),and I noticed that there is a newly added property called allowsBackgroundLocationUpdates in CLLocationManager class.

What's the relationship between this property and the location updates in the Background Modes of the Capabilities tab. What's the default value of it and does it affect apps running in iOS9?

Barrel answered 12/6, 2015 at 16:41 Comment(0)
B
109

This new property is explained in the WWDC session "What's New in Core Location".

The default value is NO if you link against iOS 9.

If your app uses location in the background (without showing the blue status bar) you have to set allowsBackgroundLocationUpdates to YES in addition to setting the background mode capability in Info.plist. Otherwise location updates are only delivered in foreground. The advantage is that you can now have location managers with background location updates and other location managers with only foreground location updates in the same app. You can also reset the value to NO to change the behavior.

The documentation is pretty clear about it:

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.

Blasto answered 13/6, 2015 at 17:20 Comment(3)
I think that this property makes confusion more than clearness. We had(and we still have) "always" and "when in use" properties that are more than clear. Why adding such confusing property. And I don't think using more than one CLLocationManager object is a best practice.Modica
Is this property necessary for region monitoring or significant change location monitoring in the background or is requestAlwaysAuthorization still good enough?Myna
I've faced with strange behavior of allowsBackgroundLocationUpdates while disabling, after being enabled. Maybe you could help me with my problem #41704802 ThanksTankoos
H
45

If you're using CoreLocation framework in your app in Xcode7(pre-released),and you may notice that there is a newly added property called allowsBackgroundLocationUpdates in CLLocationManager class.

This new property is explained in the WWDC session "What's New in Core Location". enter image description here

The default value is NO if you link against iOS 9.

If your app uses location in the background (without showing the blue status bar) you have to set allowsBackgroundLocationUpdates to YES in addition to setting the background mode capability in Info.plist. Otherwise location updates are only delivered in foreground. The advantage is that you can now have location managers with background location updates and other location managers with only foreground location updates in the same app. You can also reset the value to NO to change the behavior.

The documentation is pretty clear about it:

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.

Set Info.plist like: enter image description here

The syntax for the Info.plist configuration looks like this:

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

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

Or pull up the Capabilities tab of your app target.

enter image description here
(source: raywenderlich.com)

Use like:

_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];

I write a Demo Here (Demo2)

Hulburt answered 24/6, 2015 at 10:18 Comment(1)
Did you faced with problems with this flag? In my example project disabling it doesn't work, if it was set to true initially #41704802 ThanksTankoos
L
6
{
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];
         }
     }
}
Lectureship answered 3/5, 2016 at 10:29 Comment(1)
Just small typo MainBundle should be with lowercase M. mainBundle = [NSBundle mainBundle];Timothee
I
5

Well, I'm still using xCode 6, since 7 beta always crashes with the simulator, and I have this problem although I don't even link against iOS9! And I can't set this property since it doesn't exist in iOS8! Oh Apple, when will the torment end?!

I changed it to this xCode6 compatible version by doing this late bound invocation:

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];
        }

Confirmed working on iOS8 (doesn't do anything) and on iOS9 beta 6 (invokes the method correctly).

Invitation answered 8/9, 2015 at 16:23 Comment(0)
C
5

I faced the same location service on background Mode for iOS 9.0.x and I fixed it as recommended in this post by adding below codes

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

However it doesn't work in iOS 9.1 Does anyone have the same problem??? If so, please kindly help. Thanks

Capsule answered 4/11, 2015 at 15:18 Comment(6)
I have the same problem on iOS 9.1Uprising
@franck, I have the exactly same problem, did you resolved it?Stalinabad
@Stalinabad Sorry no, it works for me now, and I didn't understood what happen.Uprising
@Uprising did you enabled the "Audio, Air play and pip ..." option in the XCode "Background Modes" page?Stalinabad
@Uprising Yes, But it still not work. Any way, thanks for your response :-)Stalinabad
I am facing the same problem in iOS 9.1. I dont understand how to fix it. Please help if you have found any solution to this.Groping
C
0

Here is a summary of many methods that are updated from iOS 8 to iOS 9

Many APIs and codes should be searched for each framework you are using. So search in General the framework and then find these methods to update depreciated methods.

Cairn answered 1/10, 2015 at 14:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.