I have this snippet:
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!'));
}
});
Which I call like so:
try {
const { coords } = await getCurrentPosition();
// do stuff with coords
}
catch (e){
// handle the error
}
When executing this code in an iOS PWA (navigator.standalone) if I have my location settings for Safari (Settings > Privacy > Location Services > Safari Websites) set to: Ask Next Time, the getCurrentPosition() promise hangs and does not timeout, resolve or reject. It does not prompt me for my location like it does in the iOS Safari browser
If I change the settings to Never or While Using the App, then it prompts me and works fine.
I want to be able to handle the scenario where a user has set their settings to Ask Next Time whilst using a PWA.
The solution to this was fairly trivial once some colleagues and I figured it out:
What's going on here?
standalone, we're creating a promise thatrejectsafter 4 seconds (this value is arbitrary, the maximum time you want your users to wait) and pushing it to the promiseArray.promiseArrayas well.Promise.race(). The key here is that there will only be one promise in thepromiseArrayif the navigator is notstandalone, and will therefore work as intended. If the navigator is standalone, then there will be two promises in thepromiseArrayand thePromise.race()will reject from the timeout, thus rejecting fromgetUserPosition()function.