5

I am wondering if it is possible to stop WKWebView from showing the location permission prompt? ("website.com" Would Like To Use Your Current Location) I believe it is showing because the website contains a google map. I am not interested in preloading a location in its place like is shown in other SO questions. I simply don't want to use location in the WKWebView. Is there a way to stop the location permission prompt from appearing? I have tried injecting the following javascript but it doesn't work.

        let contentController = WKUserContentController()

        let scriptSource = "navigator.geolocation.getCurrentPosition = function(success, error, options) { // }; navigator.geolocation.watchPosition = function(success, error, options) { // }; navigator.geolocation.clearWatch = function(id) { // };"
        let script = WKUserScript(source: scriptSource, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
        contentController.addUserScript(script)

        let config = WKWebViewConfiguration()
        config.userContentController = contentController

        webView = WKWebView(frame: .zero, configuration: config)
        self.view = webView
user3614030
  • 481
  • 6
  • 16
  • Deactivate JavaScript – Marc T. Jul 29 '18 at 04:31
  • Javascript is still needed to load data on the website. – user3614030 Jul 29 '18 at 04:40
  • If you're inserting the script at document end (`.atDocumentEnd`) you give a chance for all javascript in the webpage to execute. Try inserting it at `.atDocumentStart` – Cristik Jul 29 '18 at 06:31
  • @Cristik it still shows the permission prompt when injectionTime is set to .atDocumentStart =/ – user3614030 Jul 29 '18 at 07:47
  • Then it might be that it's not possible to achieve it via javascript... – Cristik Jul 29 '18 at 07:48
  • I see a link to script file "website.com/js/modules/ngGeolocation.js" that seems to have all of the geolocation functions in it. It is linked at the bottom of the html. I wonder if there is a way to inject something to make this file meaningless... maybe that would work. – user3614030 Jul 29 '18 at 08:14
  • 2
    Hmm... took another look at your script, the `//` component might cause problems as it might result in the rest of the code being commented out, resulting in invalid JS code. Try also removing those from the script you inject – Cristik Jul 29 '18 at 08:33
  • Also, the functions signatures seem incorrect (though being JS it might not make a difference): https://www.w3schools.com/htmL/html5_geolocation.asp – Cristik Jul 29 '18 at 08:35
  • 1
    That was it! I just removed the // and it worked. Thank you! – user3614030 Jul 29 '18 at 09:21

2 Answers2

3

A couple of notes:

  1. .atDocumentEnd means your script will execute after the page loads, and this might result in the javascript asking for location running before you hijack the location functions; you might get better results with .atDocumentStart
  2. you have // sequences in the script, which will likely result in the rest of the script being interpreted as comments, leading to incorrect JS being injected
  3. the signature of the functions don't seem to match the HTML 5 Geolocation API, though considering we're in JS world and the function bodies are empty, it might not make a difference.

Try fixing the above issues, this might result in the behaviour you need.

Cristik
  • 30,989
  • 25
  • 91
  • 127
0

I had this same problem and the above only partially worked. I believe the more correct solution to this problem is to call the error callback with the PERMISSION_DENIED error code so the website can do what it needs to when location access is denied. Here's the code that I ended up using (I only needed the getCurrentPosition override, but you could add the watchPosition one too if you need it):

let removeLocationJS = """
navigator.geolocation.getCurrentPosition = function(success, error, options) {
    error({
        PERMISSION_DENIED: 1,
        code: 1
    });
};
"""

let removeLocation = WKUserScript(source: removeLocationJS, injectionTime: .atDocumentStart, forMainFrameOnly: true)
contentController.addUserScript(removeLocation)

let config = WKWebViewConfiguration()
config.userContentController = contentController

let webView = WKWebView(frame: .zero, configuration: config)

Really it seems like WKWebView should take care of this for you if you don't have the entry in your Info.plist, it should just automatically do this (and maybe spit a message into the console to let you know that it did). I'm gonna go file a radar...

aranasaurus
  • 345
  • 1
  • 3
  • 13