При использовании API-интерфейса geolcoation в react-native-webview меня дважды спрашивают, разрешено ли приложению использовать мое текущее местоположение. Как можно перенаправить уже (не) предоставленное разрешение на веб-просмотр?
В настоящее время я использую react-native 0.68 и react-native-webview 11.22.
Первая подсказка:
Вторая подсказка:
Меня должны спросить только один раз о разрешении на использование моей текущей геолокации.





Если кто-то столкнется с той же проблемой, я решил эту проблему с помощью следующего обходного пути. Я внедрил пользовательский javacscript в веб-просмотр, чтобы переопределить используемый API геолокации в веб-просмотре. Мой пользовательский скрипт выполняет всю связь с приложением. Приложение возвращает геолокацию, поэтому веб-просмотру не нужно запрашивать разрешение.
Пользовательский сценарий
export const getGeoLocationJS = () => {
const getCurrentPosition = `
navigator.geolocation.getCurrentPosition = (success, error, options) => {
window.ReactNativeWebView.postMessage(JSON.stringify({ event: 'getCurrentPosition', options: options }));
window.addEventListener('message', (e) => {
let eventData = {}
try {
eventData = JSON.parse(e.data);
} catch (e) {}
if (eventData.event === 'currentPosition') {
success(eventData.data);
} else if (eventData.event === 'currentPositionError') {
error(eventData.data);
}
});
};
true;
`;
const watchPosition = `
navigator.geolocation.watchPosition = (success, error, options) => {
window.ReactNativeWebView.postMessage(JSON.stringify({ event: 'watchPosition', options: options }));
window.addEventListener('message', (e) => {
let eventData = {}
try {
eventData = JSON.parse(e.data);
} catch (e) {}
if (eventData.event === 'watchPosition') {
success(eventData.data);
} else if (eventData.event === 'watchPositionError') {
error(eventData.data);
}
});
};
true;
`;
const clearWatch = `
navigator.geolocation.clearWatch = (watchID) => {
window.ReactNativeWebView.postMessage(JSON.stringify({ event: 'clearWatch', watchID: watchID }));
};
true;
`;
return `
(function() {
${getCurrentPosition}
${watchPosition}
${clearWatch}
})();
`;
};Веб-просмотр
import Geolocation from '@react-native-community/geolocation';
let webview = null;
<WebView
geolocationEnabled = { true }
injectedJavaScript = { getGeoLocationJS() }
javaScriptEnabled = { true }
onMessage = { event => {
let data = {}
try {
data = JSON.parse(event.nativeEvent.data);
} catch (e) {
console.info(e);
}
if (data?.event && data.event === 'getCurrentPosition') {
Geolocation.getCurrentPosition((position) => {
webview.postMessage(JSON.stringify({ event: 'currentPosition', data: position }));
}, (error) => {
webview.postMessage(JSON.stringify({ event: 'currentPositionError', data: error }));
}, data.options);
} else if (data?.event && data.event === 'watchPosition') {
Geolocation.watchPosition((position) => {
webview.postMessage(JSON.stringify({ event: 'watchPosition', data: position }));
}, (error) => {
webview.postMessage(JSON.stringify({ event: 'watchPositionError', data: error }));
}, data.options);
} else if (data?.event && data.event === 'clearWatch') {
Geolocation.clearWatch(data.watchID);
}
}}
ref = { ref => {
webview = ref;
if (onRef) {
onRef(webview)
}
}}
source = { url }
startInLoadingState = { true }
/>Умное решение, были ли у вас проблемы с Apple Review при его использовании? Спасибо, что поделился!
Нет, совсем нет. Я уже давно использую инъекции js для связи между веб-просмотром и мобильным устройством. Просто сейчас это необычный случай, но его приняли сразу.
Нет, вас спросят дважды. Веб-представление не является вашим родным приложением. Это то же самое, что и доступ к веб-странице, которая запрашивает ваше местоположение. Пользователь может зайти в настройки сафари и разрешить веб-сайтам использовать местоположение без запроса, но вы ничего не можете сделать в коде.