When I want to test my app with Expo Go on iOS I get this error:
[Unhandled promise rejection: Error: One of the `NSLocation*UsageDescription` keys must be present in Info.plist to be able to use geolocation.]
Stack trace:
node_modules\react-native\Libraries\BatchedBridge\NativeModules.js:104:50 in promiseMethodWrapper
node_modules\expo-modules-core\build\NativeModulesProxy.native.js:15:23 in moduleName.methodInfo.name
I added that configuration to info.plist, rebuilt the project, but I get the same error, I also reinstalled node packages, but it didn't change anything.
package.json
"dependencies": {
"@expo/vector-icons": "^12.0.0",
"expo": "~43.0.2",
"expo-location": "~13.0.4",
"expo-status-bar": "~1.1.0",
"expo-task-manager": "~10.0.3",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-paper": "4.9.2",
"react-native-web": "0.17.1",
"expo-splash-screen": "~0.13.5",
"expo-updates": "~0.10.13",
"react-native-gesture-handler": "~1.10.2",
"react-native-reanimated": "~2.2.0",
"react-native-safe-area-context": "3.3.2",
"react-native-screens": "~3.8.0"
},
"devDependencies": {
"@babel/core": "^7.12.9"
}
My js code
const { status } = await Location.requestForegroundPermissionsAsync();
if (status === "granted") {
const background = await Location.requestBackgroundPermissionsAsync();
if (background.status === "granted") {
await Location.startLocationUpdatesAsync(TASK_FETCH_LOCATION, {
activityType: Location.LocationActivityType.BestForNavigation,
showsBackgroundLocationIndicator: true,
accuracy: Location.Accuracy.BestForNavigation,
deferredUpdatesInterval: 3000,
deferredUpdatesDistance: 50,
showsBackgroundLocationIndicator: true,
}).then(() => {
Alert.alert("Turn on", null, [
{ text: "OK", onPress: () => console.log("listening gps") },
]);
});
}
}
app.json
"ios": {
"supportsTablet": true,
"infoPlist": {
"UIBackgroundModes": [
"location",
"fetch"
],
"NSLocationAlwaysAndWhenInUseUsageDescription": "Allows App to use location services in the foreground and background.",
"NSFaceIDUsageDescription": "Allows App to use Face ID for a simpler sign in."
}
}
You need to first add this to your app.json:
{
"expo": {
"ios": {
"infoPlist": {
"UIBackgroundModes": [
"location",
"fetch",
"remote-notification"
],
"NSLocationWhenInUseUsageDescription": "This app requires access to your location when open.",
"NSLocationAlwaysAndWhenInUseUsageDescription": "This app requires access to your location even when closed.",
"NSLocationAlwaysUsageDescription": "This app requires access to your location when open.",
"deploymentTarget": "14"
}
},
"plugins": [
"expo-localization",
"expo-background-fetch",
[
"expo-build-properties",
{
"android": {
"compileSdkVersion": 33,
"targetSdkVersion": 33,
"buildToolsVersion": "33.0.0"
},
"ios": {
"deploymentTarget": "14.0"
}
}
],
[
"expo-task-manager",
{
"ios": {
"minimumOSVersion": "14"
}
}
],
[
"expo-background-fetch",
{
"ios": {
"minimumOSVersion": "14"
}
}
],
[
"expo-location",
{
"locationAlwaysAndWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location.",
"locationAlwaysPermission": "Allow $(PRODUCT_NAME) to use your location.",
"locationWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location.",
"isIosBackgroundLocationEnabled": true,
"isAndroidBackgroundLocationEnabled": true
}
]
]
}
}
Then you need to run this:
npx expo prebuild --clean
npx expo run:ios
After you do a build, you need the open the app with Xcode, using this command:
open -a Xcode ios
Where "ios" is the folder where the app was built.
Then you need to sign in with your apple development account and add a certificate to the app.
After you add the certificate make sure to disable push notifications if you have a personal apple developer account by click on the trash icon on the right in the Xcode settings where you've added the certificate.
Then run the turn on development mode on your physical iphone, connect your iphone over USB and run this command:
npx expo run:ios --device
(select your iPhone that you connect over USB)
This is the only way to make background location work with expo on a physical iPhone.