【问题标题】:`navigator.geolocation.getCurrentPosition()` hangs on iOS PWA`navigator.geolocation.getCurrentPosition()` 在 iOS PWA 上挂起
【发布时间】:2021-06-10 16:20:17
【问题描述】:

我有这个sn-p:

const getCurrentPosition = () =>
  new Promise<GeolocationPosition>((resolve, reject) => {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(resolve, reject, {
        timeout: 5000,
        maximumAge: 2000,
        enableHighAccuracy: true,
      });
    } else {
      reject(new Error('Browser does not support geolocation!'));
    }
  });

我这样称呼:

try {
  const { coords } = await getCurrentPosition();
  // do stuff with coords
}
catch (e){
  // handle the error
}

在 iOS PWA (navigator.standalone) 中执行此代码时,如果我将 Safari 的位置设置 (Settings > Privacy > Location Services > Safari Websites) 设置为:Ask Next Time,@ 987654329@ promise 挂起并且不会超时、解决或拒绝。它不会像在 iOS Safari 浏览器中那样提示我输入我的位置

如果我将设置更改为NeverWhile Using the App,那么它会提示我并且工作正常。

我希望能够处理用户在使用 PWA 时将其设置设置为 Ask Next Time 的情况。

【问题讨论】:

    标签: javascript ios typescript progressive-web-apps w3c-geolocation


    【解决方案1】:

    一旦我和一些同事想通了,这个问题的解决方案就相当简单了:

    export function getUserPosition(): Promise<GeolocationPosition> {
      const promiseArray = [];
    
      if (navigator.standalone) {
        promiseArray.push(
          new Promise((resolve, reject) => {
            const wait = setTimeout(() => {
              clearTimeout(wait);
              reject('Location has timed out');
            }, 4000);
          })
        );
      }
    
      const getCurrentPositionPromise = new Promise((resolve, reject) => {
        if (navigator.geolocation) {
          navigator.geolocation.getCurrentPosition(resolve, reject, {
            timeout: 5000,
            maximumAge: 2000,
            enableHighAccuracy: true,
          });
        } else {
          reject(new Error('Browser does not support geolocation!'));
        }
      });
    
      promiseArray.push(getCurrentPositionPromise);
    
      return Promise.race(promiseArray) as Promise<GeolocationPosition>;
    }
    

    这是怎么回事?

    1. 我们正在创建一个空的 promise 数组
    2. 如果导航器被标识为standalone,我们将在 4 秒后创建一个 rejects 的 promise(此值是任意的,您希望用户等待的最长时间)并将其推送到 promiseArray。
    3. 我们正在创建另一个承诺,它会获取用户的位置并将其推送到 promiseArray 中。
    4. 然后我们返回一个从Promise.race() 的执行返回的promise。这里的关键是,如果导航器不是standalonepromiseArray 中将只有一个承诺,因此将按预期工作。如果导航器是独立的,那么promiseArray 中将有两个承诺,Promise.race() 将从超时拒绝,从而拒绝getUserPosition() 函数。

    【讨论】:

      猜你喜欢
      • 2019-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-17
      • 2019-12-18
      • 2013-06-25
      • 1970-01-01
      • 2012-03-02
      相关资源
      最近更新 更多