I'm using navigator.geolocation.getCurrentPosition() in react native and it's working fine.
But i would like to be able to react nicely if location services are turned off (a dialog box that leads the user to settings).
I found that plugin for android and i think it's going to work fine :
https://www.npmjs.com/package/react-native-android-location-services-dialog-box How should i do in iOS ?
EDIT
You can use this very well done 3rd party library
and then use it like this :
Location.getAuthorizationStatus((authorization) => {
console.log(authorization)
});
Previous answer
getCurrentPosition can take an error callback. This will be triggered if the location is not enabled.
You can do something like:
navigator.geolocation.getCurrentPosition(
(position) => {
this.setState({ position });
},
(error) => {
console.log(alert);
},
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
You can check the docs for more informations.
Related
In my App I have two windows: mainWindow and actionWindow. On my mainWindow I use the ipcRenderer.on listener to receive as message from the main process when the actionWindow is closed. The message however doesn't come through.
The mainWindow is used to control actions that take place on the actionWindow (e.g. navigate to an URL, remotely close the window, ...). I want to give the user the power to move and close the actionWindow manually as well, which is why its title bar is visible and usable.
I expose ipcRenderer.invoke for two-way communication and ipcRenderer.on to the mainWindow's renderer via contextBridge in a preload file.
This is what the code looks like (based on vite-electron-builder template)
main process
const mainWindow = new BrowserWindow({
show: false, // Use 'ready-to-show' event to show window
webPreferences: {
nativeWindowOpen: true,
webviewTag: false,
preload: join(__dirname, "../../preload/dist/index.cjs"),
},
});
const actionWindow = new BrowserWindow({
// some props
})
actionWindow.on("close", () => {
console.log("window closed")
mainWindow.webContents.send("closed", { message: "window closed" });
});
preload
contextBridge.exposeInMainWorld("ipcRenderer", {
invoke: ipcRenderer.invoke,
on: ipcRenderer.on,
});
renderer (mainWindow)
window.ipcRenderer.on("closed", () => {
console.log("message received")
// do something
});
I know for a fact that
mainWindow has access to the exposed listeners, since invoke works and the actions it fires on the main process are executed on the actionWindow as supposed + the response also comes back to the renderer.
the close listener on the actionWindow works since I can see the log window closed in my console
message received doesn't appear in my dev tools console
To me this means that either
mainWindow.webContents.send doesn't work -> the message is never sent
window.ipcRenderer.on doesn't work -> the message never reaches its destination
So either my code is buggy or Electron has recently put some restrictions on one of these methods which I'm not aware of.
Any ideas?
If there is a smarter way to do this than IPC I'm also open to that.
Ok after hours of searching, trying and suffering I (almost accidentaly) found a solution to my problem. It really seems to be the case that electron simply doesn't do anything anymore when you call the on method from your renderer.
Studying the docs about contextBridge again I saw that the way I exposed invoke and on to the renderer, was considered bad code. The safer way to do this is expose a function for EVERY ipc channel you want to use. In my case using TypeScript it looks like this:
preload
contextBridge.exposeInMainWorld("ipcRenderer", {
invokeOpen: async (optionsString: string) => {
await ipcRenderer.invoke("open", optionsString);
},
onClose: (callback: () => void) => {
ipcRenderer.on("closed", callback);
},
removeOnClose: (callback: () => void) => {
ipcRenderer.removeListener("closed", callback);
},
});
renderer(mainWindow)
window.ipcRenderer.onClose(() => {
// do sth
});
window.ipcRenderer.invokeOpen(JSON.stringify(someData)).then(() => {
// do sth when response came back
});
NOTE: To prevent memory leaks by creating listeners on every render of the mainWindow you also have to use a cleanup function which is provided with removeOnClose (see preload). How to use this function differs depending on the frontend framework. Using React it looks like this:
const doSth= () => {
console.log("doing something")
...
};
useEffect(() => {
window.ipcRenderer.onClose(doSth);
return () => {
window.ipcRenderer.removeOnClose(doSth);
};
}, []);
Not only is this a safer solution, it actually suddenly works :O
Using the cleanup function we also take care of leaks.
I'm attempting to use HTML5 Geolocation on IE11, but despite allowing location permission, I get an error, "This site does not have permission to use the Geolocation API."
To replicate:
Open any site in IE11 (I'm user browerstack to emulate a Windows 10)
Copy/paste the following code in the console:
var options = {
enableHighAccuracy: false,
timeout: 1000000,
maximumAge: 0
};
function success(pos) {
var crd = pos.coords;
console.log('got your position');
}
function error(err) {
console.log(err);
}
navigator.geolocation.getCurrentPosition(success, error, options);
Click "Allow Once" when the location prompt appears
Observe the Resulting Error Message, "This site does not have permission to use the Geolocation API."
My browserstack is running IE11 version 11.1.17134.0, on a Windows 10.
Thanks in advance for your help!
I'm having trouble with a simple task. In Xcode 13, you can create a Safari Extension App (Safari Web Extension for iOS 15).
From looking around, the Shared Extension has various js resources: background.js, content.js, and popup.js.
Popup.js is the presented modal when you launch your Safari web extension. In popup.html, you can add elements to the popup DOM (such as text, button, etc). In my popup, I have a button which I have wired up in popup.js. When I press this button, I want to notify content.js of this event. How do I do this?
My current code adds an event listener to the button containing browser.runtime.sendMessage({ type: "start" }); in popup.js.
Xcode's template includes the following in content.js:
browser.runtime.sendMessage({ greeting: "hello" }).then((response) => {
console.log("Received response: ", response);
});
browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log("Received request: ", request);
});
As far as I can tell, the JS is running in popup.js, but I am not seeing anything in console.log for content.js. Sidenote: console.log is really hard to use for iPhone Safari app.
I've found this documentation, but it only discusses passing message from macOS app to JS. I'm trying to pass message from iOS popup to content.js.
See if this works
const isChrome = !window["browser"] && !!chrome;
const browser = isChrome ? chrome : window["browser"];
function sendMessageToContent(message) {
browser.tabs.query({ active: true }).then(function (currentTabs) {
if (currentTabs[0].id >= 0) {
browser.tabs.sendMessage(currentTabs[0].id, message);
}
});
}
I'm using axios to fetch data for my React Native app and I'm having an issue only for iOS. I am able to fetch data from my server perfectly fine, however if I change any data from my API, the changes doesn't reflect in iOS at all, only when I re-install the app then the changes will take place. I'm still not able to pinpoint what is causing the issue. This is only happening in iOS, Android works perfectly fine.
Fetch Data code:
axios.get('http://www.example.com/api')
.then((response) => {
// console.log(response);
this.setState({ data: response.data, loading: false });
});
Please let me know if I miss out any information.
If this has already been asked, I would greatly appreciate if you are able to point me in the right direction.
Thank you so much!
my guess is that the page is read from the cache and so you get an old copy.
what you need to do is to add a date stamp to the link, in order to force the app to load a 'fresh' page.
it goes something like that:
axios.get('http://www.example.com/api?dt='+(new Date()).getTime())
.then((response) => {
// console.log(response);
this.setState({ data: response.data, loading: false });
});
It can be resolved by adding headers: {'Cache-Control': 'no-cache'} to the header.
axios.get('http://www.example.com/api',
headers: {'Cache-Control': 'no-cache'})
.then((response) => {
// console.log(response);
this.setState({ data: response.data, loading: false });
});
Greetings Everyone,
I am creating a web application that uses the Geolocation API to locate the end user. It works great on almost every platform I can think of except for Internet Explorer 9. Things get a little stranger though. If I have my Google Toolbar loaded into my Internet Explorer browser window, everything sails smoothly. Here is the offending chunk of code that I have been working with:
if (navigator.geolocation) {
var locationMarker = null;
navigator.geolocation.watchPosition(
function( position ){
var point = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
if (!locationMarker) {
locationMarker = addMarker(
position.coords.latitude,
position.coords.longitude,
"Initial Position"
);
}
else{
updateMarker(
locationMarker,
position.coords.latitude,
position.coords.longitude,
"Updated / Accurate Position"
);
};
map.setCenter(point);
if (map.zoom < 17){
map.setZoom(17);
};
},
function( error ){
console.log( "Something went wrong: ", error );
},
{
timeout: (5 * 1000),
maximumAge: (1000 * 60 * 15),
enableHighAccuracy: true
}
);
}
else {
alert("Geolocation is not supported by this browser");
}
Whenever I access my application with Internet Explorer 9 I get the "Geolocation is not supported by this browser" alert. That is unless I have my Google Toolbar active. If the Google Toolbar is active however, then the Google Toolbar handles the permissions.
How do I get geolocation to work in IE9? My application works flawlessly in Safari, Firefox, Chrome, iOS and Android. I am totally stumped.
Thanks, Tyler Waring
user1303379,
IE9 and IE10 both support geolocation, however earlier versions of IE do not support it ( reference http://caniuse.com/#feat=geolocation ). Here is a blog post by IE about geolocation in IE9 http://blogs.msdn.com/b/ie/archive/2011/02/17/w3c-geolocation-api-in-ie9.aspx and here is a test page using navigator.geolocation.watchPosition like you are above.
For browsers that don't support geolocation you may consider using one of the geolocation polyfills listed here https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills
IE9 & IE10 ask the user if they would like to share their location http://cl.ly/image/0X0o2F0s1N03 My guess is that you may have denied access to your location at some point.
The Google Toolbar added a feature to determine geolocation back in the IE8 days http://googletoolbarhelp.blogspot.com/2010/02/google-toolbar-6413211732-for-ie.html From what you describe it sounds like the Google Toolbar started to provide geolocation since the native IE9 geolocation was denied access.