【问题标题】:Expo Location tracking denied for IOSIOS 拒绝世博会位置跟踪
【发布时间】:2022-10-02 08:53:01
【问题描述】:

我试图在 IOS 上跟踪用户位置,但它总是被拒绝。我在 app.json 文件中添加了所有必要的依赖项,但我不断收到相同的错误消息:

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

这是我的 app.json 文件

{
  \"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\"
    }
  }
}

零件:

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>
    )
  }
}

我不得不提到这段代码在 android 上完美运行。

有谁知道我做错了什么?

    标签: react-native google-maps geolocation expo location


    【解决方案1】:

    因此,无论谁正在努力使用 expo 在 iOS 上使用导航,请注意,为了让 expo 从 app.json 中进行更改,您必须在 Mac 上构建您的应用并使用您的 Apple 开发者帐户发布您的应用.

    【讨论】:

      猜你喜欢
      • 2020-05-02
      • 2021-04-03
      • 1970-01-01
      • 1970-01-01
      • 2019-12-22
      • 2018-05-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      相关资源
      最近更新 更多