Location not updating on IOS

Please provide the following:

  1. SDK Version: 46
  2. Platforms(Android/iOS/web/all):
    iOS

im trying to track user location on iOS but it always keeps being denied. I have added all necessary dependencies in the app.json file but i keep getting the same error message saying :

[Unhandled promise rejection: Error: One of the NSLocation*UsageDescription keys must be present in Info.plist to be able to use geolocation.]

This is my app.json file

{
  "expo": {
    "name": "Test App",
    "slug": "TestApp",
    "version": "1.0.0",
    "privacy":"public",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "userInterfaceStyle": "light",
    "sdkVersion": "46.0.0",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
  
    "ios": {
      "bundleIdentifier": "com.companyname.appTest" ,  
      "buildNumber": "1.0.0",
      "supportsTablet": true,
      "config": {"googleMapsApiKey": "apikey"},
      "infoPlist":{
        "NSLocationUsageDescription":"App requires location even when the App is backgrounded.",
        "NSLocationWhenInUseUsageDescription":"App requires location even when the App is backgrounded.",
        "NSLocationAlwaysUsageDescription":"App requires location even when the App is backgrounded.",
        "NSLocationAlwaysAndWhenInUseUsageDescription":"App requires location even when the App is backgrounded.",
        "UIBackgroundModes": [
          "location",
          "fetch"
        ]
      }
    },
    "android": {
      "package": "com.companyname.appTest",
      "permissions":["ACCESS_COARSE_LOCATION","ACCESS_FINE_LOCATION","ACCESS_BACKGROUND_LOCATION","FOREGROUND_SERVICE"],
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#FFFFFF"
      },
      "config": {
        "googleMaps": { "apiKey": "apikey" }   
     },
     "versionCode": 1
    },
    "web": {
      "favicon": "./assets/favicon.png"
    }
  }
}

Component:

let foregroundSubscription = null
const LOCATION_TASK_NAME = "LOCATION_TASK_NAME";

TaskManager.defineTask(LOCATION_TASK_NAME, async ({ data, error }) => {
  if (error) {
    console.error(error)
    return
  }
  if (data) {
    // Extract location coordinates from data
    const { locations } = data
    const location = locations[0]
    if (location) {
      let lat = locations[0].coords.latitude;
      let long = locations[0].coords.longitude;

     console.log(lat,long);
  }
})

export default function OrderLocation ({ route, navigation }) {
  const mapView = React.createRef();
  const isFocused = useIsFocused();
  const [position, setPosition] = useState(null);
  const [isTracking, setIsTracking] = useState(false);
  const [courierLocation, setCourierLocation] = useState({latitude:0,longitude:0});
  const [address, setAddress] = useState("");
  const [userRole, setUserRole] = useState(null);
  const [loading, setLoading] = useState(true);
  const [region, setRegion] = useState({
    latitude: 0,
    longitude: 0,
    latitudeDelta: 0.12,
    longitudeDelta: 0.12,
  });

  useEffect(() => { 
    if(isFocused){
       requestPermissions();
    }
    },[isFocused]);
}
const requestPermissions = async () => {
  const foreground = await Location.requestForegroundPermissionsAsync()
  if (foreground.granted) await Location.requestBackgroundPermissionsAsync()
}

 
  const startForegroundUpdate = async () => {
    // Check if foreground permission is granted
    const { granted } = await Location.getForegroundPermissionsAsync()
    if (!granted) {
      console.log("location tracking denied")
      return
    }

    // Make sure that foreground location tracking is not running
    foregroundSubscription?.remove()
    setIsTracking(true);

    // Start watching position in real-time
    foregroundSubscription = await Location.watchPositionAsync(
      {
        // For better logs, we set the accuracy to the most sensitive option
        accuracy: Location.Accuracy.BestForNavigation,
        timeInterval:3000
      },
      location => {
        setPosition(location.coords);
        setRegion(location.coords);
      }
    )
    startBackgroundUpdate();
  }

  // Stop location tracking in foreground
  const stopForegroundUpdate = () => {
    foregroundSubscription?.remove()
    setPosition(null)
    //setRegion(location.coords);
    stopBackgroundUpdate();
    setIsTracking(false);
  }

  // Start location tracking in background
  const startBackgroundUpdate = async () => {
    // Don't track position if permission is not granted
    const { granted } = await Location.getBackgroundPermissionsAsync()
    if (!granted) {
      console.log("location tracking denied")
      return
    }

    // Make sure the task is defined otherwise do not start tracking
    const isTaskDefined = await TaskManager.isTaskDefined(LOCATION_TASK_NAME)
    if (!isTaskDefined) {
      console.log("Task is not defined")
      return
    }

    // Don't track if it is already running in background
    const hasStarted = await Location.hasStartedLocationUpdatesAsync(
      LOCATION_TASK_NAME
    )
    if (hasStarted) {
      console.log("Already started")
      return
    }
    setIsTracking(true);

    await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
      // For better logs, we set the accuracy to the most sensitive option
      accuracy: Location.Accuracy.BestForNavigation,
      // Make sure to enable this notification if you want to consistently track in the background
      showsBackgroundLocationIndicator: true,
      timeInterval:180000,
      foregroundService: {
        notificationTitle: "Location",
        notificationBody: "Location tracking in background",
        notificationColor: "#fff",
      },
    })
  }

  // Stop location tracking in background
  const stopBackgroundUpdate = async () => {
    const hasStarted = await Location.hasStartedLocationUpdatesAsync(
      LOCATION_TASK_NAME
    )
    if (hasStarted) {
      await Location.stopLocationUpdatesAsync(LOCATION_TASK_NAME)
      console.log("Location tacking stopped")
    }
  }

    return (
      <Layout style={styles.courerContainer}>
        <Layout style={styles.trackingButtons}>
          <Button appearance='ghost' onPress={startForegroundUpdate}>Allow app to use location</Button>
          <Button appearance='ghost' status="danger" onPress={stopForegroundUpdate} >Turn off tracking</Button>
        </Layout>
        {isTracking ?
          <Layout>
            <Text>Longitude: {position?.longitude}</Text>
            <Text>Latitude: {position?.latitude}</Text>
       </Layout>:<Text></Text>
        }
       
        <Layout>
       <MapView provider={PROVIDER_GOOGLE} style={styles.map}  ref={mapView} initialRegion={region}  followUserLocation={true} zoomEnabled={true} showsUserLocation={true} >
        </MapView>
        </Layout>
      </Layout>
    )
  }
}

I have to mention this code works perfectly on android. But when i use iphone (phisical device) locations is not being updated. When i enable foreground pemission it takes the location the first time but then its not updating it.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.