【问题标题】:How is it determined when to prompt user location permissions on iOS safari?iOS safari 上何时提示用户位置权限是如何确定的?
【发布时间】:2022-01-10 15:31:12
【问题描述】:

当在移动设备上使用geolocation.getCurrentPosition API 时,目前经过测试的 iOS 系统会根据页面在会话中多次提示用户。与桌面站点(例如 Windows 10 上的 Chrome)相比,一旦用户点击Allow,除非明确禁用,否则将不再提示他们提供权限。 iOS Safari 似乎是基于会话的,然后可能是基于会话内的页面?

想知道是否有人知道 Apple 是否为此权限检查定义了明确的规则? maximumAge 是否也对提示用户的频率起作用?

  const LOCATION_OPTIONS = {
   timeout: 15000,
   enableHighAccuracy: true,
   maximumAge: 86400000,
  };

  useEffect(() => {
    const { geolocation } = navigator;

    // If the geolocation is not defined in the used browser we handle it as an error
    if (!geolocation) {
      setError("Geolocation is not supported.");
      return;
    }

    // Call Geolocation API
    geolocation.getCurrentPosition(handleSuccess, handleError, options);
  }, [options]);

  return { location, error };

NextJS 代码沙盒示例 https://u11vn.sse.codesandbox.io/

【问题讨论】:

  • 您能告诉我您使用的是哪种语言吗?您是否使用 JavaScript 调用 geolocation.getCurrentPosition?也告诉我你用的是哪个IOS版本?
  • 是的,我正在使用 Javascript。

标签: javascript ios geolocation mobile-safari


【解决方案1】:

在网页中执行以下操作/或使用带有弹出对话框的导航器

 var options = {
  enableHighAccuracy: true,
  timeout: 7000,
  maximumAge: 0
};

function log(data) {
  const tag = document.createElement('p');
  tag.textContent = data;
  document.body.appendChild(tag);
}

function success(pos) {
  var crd = pos.coords;
  console.log('Successfully determined a user position:', crd);

  log('Your current position is:');
  log(`Latitude : ${crd.latitude}`);
  log(`Longitude: ${crd.longitude}`);
  log(`More or less ${crd.accuracy} meters.`);
}

function error(err) {
  console.warn(`ERROR(${err.code}): ${err.message}`);
}

navigator.geolocation.getCurrentPosition(success, error, options);

或者

$scope.watchId = navigator.geolocation.watchPosition(function (position) {
                        if ($scope.t1 == 0) {
                            $scope.t1 = position.timestamp;
                        } else {
                            if (Math.abs($scope.t1 - position.timestamp) > 5000) {
                                $scope.t1 = position.timestamp;
                                SellerRef.update({ Location: { Lat: position.coords.latitude, Long: position.coords.longitude } })
                            }
                        }
    
                    },
                        function (error) {
                            if (error.code == 1) {
                                  $scope.showAlert("An error occured \n" + " Please goto Settings->Privacy->LocationServices and give permission for " + bowser.name + " which is your browser ");
                            }
    
                        }
                    ); 

用于在应用内加载您的网络

  • 然后使用webView,只需将位置权限描述添加到info.plist文件中。
  • 添加NSLocationWhenInUseUsageDescriptionNSLocationAlwaysUsageDescriptionNSLocationUsageDescription

什么是地理定位错误,看here

navigator.geolocation.getCurrentPosition(success => {
  /* Do some magic. */
}, failure => {
  if (failure.message.startsWith("Only secure origins are allowed")) {
    // Secure Origin issue.
  }
});

在 manifest.webapp 文件中包含/设置“required_features”选项:

{
  "required_features": ["geolocation"]
}

用户:

在 iPhone 上:

Settings -> Location Services -> [your Browser] [apple ref][1]

Chrome 需要 https 来使用地理位置


疑难解答&&权限检查/调试日志

检查,用户的操作系统和浏览器BOTH开启了定位服务,用户的浏览器支持检查定位服务

    // options for current position
    const navigatorLocationOptions = {
      enableHighAccuracy: true,
      timeout: 7000,
      maximumAge: 0
    };
 
    // does browser have geo services enabled
    navigator.permissions.query({name:'geolocation'})
      .then((result) => {
        
        if (result.state === 'granted') {// you are good
          navigator.geolocation.getCurrentPosition(position => {
             console.log('granted user location permission', position );
              
             //.. do your stuff

          }, (error) => {
            // OS services are not enabled
            console.log('Please turn on OS located services', navigator);
            errorLocation();
          }, navigatorLocationOptions);

        } else {
          // browser issues seriveces
          console.log('Browser location services disabled', navigator);
          errorLocation();
        }
      }, (error) => {
        /* Browser doesn't support querying for permissions */
        console.log('Please turn on BROWSER location services', navigator);
        errorLocation()
      }
    );


    //handle errors
    function errorLocation() {
      ...
    }

【讨论】:

  • 这是关于如何实现地理定位和权限 API 的非常全面的答案,但没有解释浏览器用来确定何时提示的过程
【解决方案2】:

不幸的是,似乎无法在 Safari 中永久授予网站访问 iPhone 隐私(如摄像头位置)的权限。但在用户端,可以设置三个选项(AskAllowDeny

如果您在 iOS WKWebView 中使用 JavaScript,您可以通过 App location API 获取请求位置的 workaround

如果您在网络上使用 JavaScript,那么您将无法实现这一点。

【讨论】:

  • 是的,肯定没有永久的方式,但我觉得奇怪的是,在我的用例中,每个会话不止一次。我将尝试将 codepen 放在一起或复制,因为我的理解是它应该是每个域一次/可能每个 maximumAge 但对我来说切换到不同的页面再次询问。我显然可以自己缓存它,但把它搞砸会很危险。
猜你喜欢
  • 2018-03-29
  • 2020-12-02
  • 2020-09-21
  • 2015-09-30
  • 2016-06-22
  • 1970-01-01
  • 2015-04-27
  • 2020-08-24
  • 2017-07-06
相关资源
最近更新 更多