Все, что я прочитал, говорит, что для того, чтобы проверить, доступна ли геолокация, нужно проверить 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 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 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
метод doSomething
до того, как получит координаты.
Я думаю, что эта проверка на совместимость путем проверки на наличие объекта геолокации:
// check for Geolocation support
if (navigator.geolocation) {
console.log('Geolocation is supported!');
}
else {
console.log('Geolocation is not supported for this Browser/OS.');
}
Я говорил слишком рано, и принял слишком рано. В моем примере перемещение метода за пределы проверки геолокации всегда приводило к "провалу" проверки геолокации, поскольку getCurrentPosition
является асинхронным. Исправление (я мог поклясться, что я пробовал это раньше) заключается в использовании попытки/улова в проверке.
// 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)
{
// ...
}