IOS 拒绝世博位置追踪

问题描述 投票:0回答:2

我尝试在 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
2个回答
1
投票

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


0
投票

对于那些仍在为此苦苦挣扎的人,我找到了一个解决方案,并将其发布在这里 错误:Info.plist 中必须存在“NSLocation*UsageDescription”键之一才能使用地理定位

© www.soinside.com 2019 - 2024. All rights reserved.