65

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?

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
tounaobun
  • 14,570
  • 9
  • 53
  • 75

6 Answers6

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.

mfaani
  • 33,269
  • 19
  • 164
  • 293
Felix
  • 35,354
  • 13
  • 96
  • 143
  • 7
    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. – androniennn Nov 05 '15 at 10:22
  • Is this property necessary for region monitoring or significant change location monitoring in the background or is `requestAlwaysAuthorization` still good enough? – Awesome-o Feb 01 '16 at 01:56
  • I've faced with strange behavior of allowsBackgroundLocationUpdates while disabling, after being enabled. Maybe you could help me with my problem http://stackoverflow.com/questions/41704302/disabling-allowsbackgroundlocationupdates-cllocationmanager-doesnt-work-after Thanks – Sander Jan 18 '17 at 10:09
44

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)

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
ChenYilong
  • 8,543
  • 9
  • 56
  • 84
  • Did you faced with problems with this flag? In my example project disabling it doesn't work, if it was set to true initially http://stackoverflow.com/questions/41704302/disabling-allowsbackgroundlocationupdates-cllocationmanager-doesnt-work-after Thanks – Sander Jan 18 '17 at 10:14
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];
         }
     }
}
Raviteja
  • 3,399
  • 23
  • 42
  • 69
Manish Nahar
  • 834
  • 10
  • 24
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).

TalL
  • 1,661
  • 16
  • 16
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

Navnath Godse
  • 2,233
  • 2
  • 23
  • 32
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.