关闭位置服务后,navigator.gelocation在iOS上仍为true

时间:2019-02-28 15:26:45

标签: javascript ios geolocation

我读过的所有内容都说,为了检查地理位置是否可用,请检查navigator.geolocation。但是,在关闭了位置服务的iOS上,它仍然可以通过检查。

它永远不会到达else

注意:我正在通过https进行测试。

if(navigator.geolocation)
{
    // on iOS safari, with location services off (globally or at the app level) this will log
    console.log('navigator.geolocation passes');
    // navigator.geolocation.getCurrentPosition does exist
    console.log(navigator.geolocation.getCurrentPosition);

    // attempt to make the call
    navigator.geolocation.getCurrentPosition((position)=>
    {
        // this will not get called
        console.log('successfully retrieved position')
    },
    (error)=>
    {
        // this will not get called
        console.log('error: ', error)
    })
}
else
{
    // I would expect this to be called but it doesn't get called
    console.log('geolocation unavailable')
}

现在,我不在试图关闭位置服务时获取位置,但是问题是当它们关闭时,它不应该通过检查。

我想作为最后的选择,我可以将一个变量设置为坐标并检查它们是否未定义,或者不依赖于上面的代码块,但是如果有更好的方法来检查它,那么我想为此。

编辑:我还应该提到,这仅在清除浏览器设置后才在页面的第一次加载中发生(至少在我看来)。第一次加载时,它将通过检查,然后挂起,因为不会调用其他任何东西。在第二次加载时,它似乎没有通过检查,因此调用了我们的后备选项。

编辑:解决方案用于在检查之外设置变量。

// create a variable to hold the coordinates
let _coords = undefined;
// this is only a compatibility check
// not a check if it's available
if(navigator.geolocation)
{
  // on iOS safari, with location services off (globally or at the app level)
  // this block will be reached

  // attempt to make the call to getCurrentPosition
  navigator.geolocation.getCurrentPosition((position)=>
  {
    // this will not get called because location services are off
    // doing something like doSomething(position.coords) will not get called
    // instead, set the variable
    _coords = position.coords;
  },
  (error)=>
  {
    // this will not get called since it's not an error
    // doSomething(undefined);
  })
}
else
{
    // this block will not get reached since geolocation IS available,
    // just not allowed. So again,
    // doSomething(undefined) will not happen
    console.log('geolocation unavailble')
}
// pass the variable (coords or undefined) to doSomething
doSomething(coords)

上面的方法不能解决整个问题,因为如果用户确实启用了定位服务,则getCoordinates是异步的,因此它将在接收坐标之前调用doSomething方法。

2 个答案:

答案 0 :(得分:1)

我认为此检查是通过测试地理位置对象的存在来实现兼容性:

// check for Geolocation support
if (navigator.geolocation) {
  console.log('Geolocation is supported!');
}
else {
  console.log('Geolocation is not supported for this Browser/OS.');
}

答案 1 :(得分:0)

我讲得太早了,接受得太早了。在我的示例中,将方法移至地理位置检查之外会导致始终“失败”地理位置检查,因为getCurrentPosition是异步的。解决方法(可能以前曾宣誓曾尝试过此方法)是在检查中使用try / catch。

// geolocation
if(navigator.geolocation)
{
  // try to get the current position
  try {
    navigator.geolocation.getCurrentPosition((position)=>
    {
      // great success! use the coordinates
      doSomething(position.coords);
    },
    (err)=>
    {
      // failed
      console.log(err);
      // most likely due to a PositionError
      // err.code === 1 (PERMISSION_DENIED)
      doSomething();
    })

  } catch (err) {
    // any other error
    console.log(err);
  }
}
else
{
  // geolocation not supported
  doSomething();
}

function doSomething(coords=undefined)
{
  // ... 
}