expo: [expo-location] ios doesn't support background when-in-use
Summary
Please correct me if I’m mistaken, but it appears that expo-location doesn’t conform to the iOS spec in terms of when the “when in use” vs. “always” location permission is applicable.
From the Apple documentation
- “Location services are available to apps with CLAuthorizationStatus.authorizedWhenInUse only while the app is ‘in use’.”
- “an app is considered in use: […] When the app shows the background location usage indicator (showsBackgroundLocationIndicator).”
However according to the Expo Location documentation
- The only method that supports
showsBackgroundLocationIndicatorisLocation.startLocationUpdatesAsync. Location.startLocationUpdatesAsyncis a background location method.- “In order to use Background Location Methods […] On iOS it must be granted with Always option”
These are pretty clearly not in agreement.
According to Apple: the “when in use” permission should allow you to use location services when the app is running in the foreground or otherwise showing the background location usage indicator.
According to Expo: the “always” permission is required in order to show the background location usage indicator.
Managed or bare workflow? If you have ios/ or android/ directories in your project, the answer is bare!
bare
What platform(s) does this occur on?
iOS
SDK Version (managed workflow only)
41.0.1
Environment
Expo CLI 4.2.1 environment info: System: OS: macOS 11.2.2 Shell: 3.2.57 - /bin/bash Binaries: Node: 14.15.0 - /usr/local/bin/node npm: 6.14.8 - /usr/local/bin/npm Watchman: 2021.08.02.00 - /usr/local/bin/watchman Managers: CocoaPods: 1.10.2 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4 IDEs: Xcode: 12.5.1/12E507 - /usr/bin/xcodebuild npmPackages: expo: ^41.0.1 => 41.0.1 react: 16.13.1 => 16.13.1 react-dom: 16.13.1 => 16.13.1 react-native: 0.63.4 => 0.63.4 react-native-web: ~0.13.12 => 0.13.18 npmGlobalPackages: expo-cli: 4.2.1 Expo Workflow: bare
Reproducible demo or steps to reproduce from a blank project
I’m fairly certain that this doesn’t work by design, but based on the docs linked in the issue summary, it would appear the design is flawed.
await Location.requestForegroundPermissionsAsync();
await Location.startLocationUpdatesAsync(
'LOCATION_UPDATER',
{
accuracy: Location.LocationAccuracy.High,
showsBackgroundLocationIndicator: true
});
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 23 (4 by maintainers)
Activity On Wed, Aug 10, 2022 at 10:08 AM github-actions[bot] < @.***> wrote:
Seems to me that this could be resolved by defining the foregroundService property of startLocationUpdatesAsync. With that, the task manager task will be a foreground task and therefore the “always” permission is not required. I think you get the “blue pill” indication when the foregroundService property is defined as well.
I really think the docs should be more specific about this though, since the startLocationUpdatesAsync is not only for background services but for foreground services as well (which does not require the always-permission) I think most fitness tracking services are using a foreground service in this way, at least from my understanding.
In summary, a task defined by expo-task-manager can be either a background task or a foreground task. Which it is depends on if the foregroundService property on the startLocationUpdatesAsync is defined or not. A background task needs the always permission but a foreground service does not. A foreground service is killed when the app is killed, but not when the phone is locked or if another app is in focus.
Not solved
Same issue our customers get spoked by the required “Always”. Other trackers can track in background with “When in use” permission only, Why not in Expo apps ?
Has anyone found a work-around? I’m not particularly looking to eject my project. Strange how expo missed the mark on this fairly common location use case…