Location "when in use" permission

  1. SDK Version: 44.0.1
  2. Platforms: iOS and Android

Dear Expo Team,
we are creating an app to track the activity of cyclists and runners. On iOS, geolocation works in the background, but it is necessary to activate “always”, but according to Apple’s policies it is not recommended to always use it if you do not use geo-fences (as in our case).

https://developer.apple.com/documentation/corelocation/choosing_the_location_services_authorization_to_request

Unfortunately, switching from “always” to “when in use” the application is unable to create the background process.

The most important tracking applications such as Strava, Runtastic, Runkeeper allow geolocation in the background but with only “when in use” permission.

Will it always be like this or do you plan to adapt to Apple’s requests?

Many thanks.

Romeo - Valxer

Hey @ironmanromeo, I’ll have to relay this internally to see if we have any further information or updates regarding this.

Cheers,
Adam

Hi Adam,

Thanks for your prompt reply.

Our client believe it’s strategic "when in use” permission only because competing applications are able to track activity without the need for too intrusive privacy like “always”. Our client fears that some users may delete the application after discovering that it only works when privacy is “always”.

After a day spent trying to figure out how to solve the problem digging in Expo Location library I found that there would be a quick and painless solution.These are settings for having what we want:

  1. When in use auth
  2. App registers for location updates in info.plist
  3. locationManager.allowsBackgroundLocationUpdates = YES;
  4. locationManager.showsBackgroundLocationIndicator = YES;
  5. [locationManager startUpdatingLocation];

https://developer.apple.com/documentation/corelocation/cllocationmanager/1620568-allowsbackgroundlocationupdates
(Very long load page…)

  • (void)startStandardUpdates
    {
    // Create the location manager if this object does not
    // already have one.
    locationManager = [[CLLocationManager alloc] init];

locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;

// Set a movement threshold for new events.
locationManager.distanceFilter = 5; // meters

locationManager.allowsBackgroundLocationUpdates = YES;
locationManager.showsBackgroundLocationIndicator = YES;

[locationManager requestWhenInUseAuthorization];

[locationManager startUpdatingLocation];
}

Schermata 2022-01-04 alle 23.10.11.png

Application will get location updates in background also with:

Location.watchPositionAsync

https://github.com/expo/expo/blob/master/packages/expo-location/ios/EXLocation/EXLocation.m

CLLocationManager *locMgr = [self locationManagerWithOptions:options];

  • (CLLocationManager *)locationManagerWithOptions:(nullable NSDictionary *)options
    {
    CLLocationManager *locMgr = [[CLLocationManager alloc] init];
    locMgr.allowsBackgroundLocationUpdates = NO;

if (options) {
locMgr.distanceFilter = options[@“distanceInterval”] ? [options[@“distanceInterval”] doubleValue] ?: kCLDistanceFilterNone : kCLLocationAccuracyHundredMeters;

if (options[@“accuracy”]) {
EXLocationAccuracy accuracy = [options[@“accuracy”] unsignedIntegerValue] ?: EXLocationAccuracyBalanced;
locMgr.desiredAccuracy = [self.class CLLocationAccuracyFromOption:accuracy];
}
}
return locMgr;
}

I think an easy solution could be add them by settings options:

if (options) {
locMgr.distanceFilter = options[@“distanceInterval”] ? [options[@“distanceInterval”] doubleValue] ?: kCLDistanceFilterNone : kCLLocationAccuracyHundredMeters;

locMgr.allowsBackgroundLocationUpdates = [options[@“allowsBackgroundLocationUpdates”] etc etc
locMgr.allowsBackgroundLocationIndicator = [options[@“allowsBackgroundLocationIndicator”] etc etc

if (options[@“accuracy”]) {
EXLocationAccuracy accuracy = [options[@“accuracy”] unsignedIntegerValue] ?: EXLocationAccuracyBalanced;
locMgr.desiredAccuracy = [self.class CLLocationAccuracyFromOption:accuracy];
}
}

Using this solution it would no longer be necessary to use Location.startLocationUpdatesAsync which requiring the creation of a TaskManager (which makes sense when using the GeoFence service) must necessarily request the “always” permission.

What do you think?

Many thanks.

Romeo

Romeo Mariani

I started using Expo for a project that will be released recently. The work done by the team to create a framework that simplifies the work for developers is very positive. The new method of compiling the apps for publication on the respective stores is interesting. Unfortunately, I cannot say the same about the part of Geolocation in the background that I have been waiting for for a long time. It can be seen from the code that it has not been updated because it forces the use of policies that are too inadequate (Always). Even worse that no one has given any signal these days, as I think no response will follow this post. I was considering the hypothesis of entrusting the publication part to Expo but I don’t think it will be possible at this stage to be able to rely on this service. Too risky. Such a pity. A missed opportunity.