What factors are taken into consideration when deciding the timing to prompt for user location permissions on iOS Safari?

When utilizing the geolocation.getCurrentPosition API on mobile, particularly iOS in this case, users may be prompted multiple times within a session based on the page they are visiting. This differs from desktop browsers like Chrome on Windows 10, where users are generally only prompted for permission once and then not again unless specifically revoked. It appears that the behavior in iOS Safari is session-dependent with possible variations on a per-page basis within a session. Do you know if Apple has established specific guidelines governing these permission checks? Additionally, could the maximumAge parameter influence how frequently the user is prompted?

  const LOCATION_OPTIONS = {
   timeout: 15000,
   enableHighAccuracy: true,
   maximumAge: 86400000,
  };

  useEffect(() => {
    const { geolocation } = navigator;

    // If the geolocation is not defined in the used browser we handle it as an error
    if (!geolocation) {
      setError("Geolocation is not supported.");
      return;
    }

    // Call Geolocation API
    geolocation.getCurrentPosition(handleSuccess, handleError, options);
  }, [options]);

  return { location, error };

Check out this sample NextJS CodeSandbox:

Answer №1

Regrettably, there appears to be no permanent solution for granting website access to iPhone privacy features such as camera location through Safari. However, users do have three options (Ask, Allow, Deny) that they can choose from.

If you are using JavaScript in iOS with WKWebView, there is a workaround available that allows you to request location using the App location API. You can find more information on this at this link.

Unfortunately, if you are using JavaScript on a web page, achieving this functionality is not possible.

Answer №2

Utilize the following code in your web application or employ the navigator with a popup dialog:

 var options = {
  enableHighAccuracy: true,
  timeout: 7000,
  maximumAge: 0
};

function log(data) {
  const tag = document.createElement('p');
  tag.textContent = data;
  document.body.appendChild(tag);
}

function success(pos) {
  var crd = pos.coords;
  console.log('Successfully determined a user position:', crd);

  log('Your current position is:');
  log(`Latitude : ${crd.latitude}`);
  log(`Longitude: ${crd.longitude}`);
  log(`More or less ${crd.accuracy} meters.`);
}

function error(err) {
  console.warn(`ERROR(${err.code}): ${err.message}`);
}

navigator.geolocation.getCurrentPosition(success, error, options);

Alternatively,

$scope.watchId = navigator.geolocation.watchPosition(function (position) {
                        if ($scope.t1 == 0) {
                            $scope.t1 = position.timestamp;
                        } else {
                            if (Math.abs($scope.t1 - position.timestamp) > 5000) {
                                $scope.t1 = position.timestamp;
                                SellerRef.update({ Location: { Lat: position.coords.latitude, Long: position.coords.longitude } })
                            }
                        }
    
                    },
                        function (error) {
                            if (error.code == 1) {
                                  $scope.showAlert("An error occured \n" + " Please goto Settings->Privacy->LocationServices and give permission for " + bowser.name + " which is your browser ");
                            }
    
                        }
                    ); 

If you want to load your web within an app,

  • You can simply add location permission descriptions to the info.plist file using webView.
  • Add
    NSLocationWhenInUseUsageDescription
    as opposed to NSLocationAlwaysUsageDescription or NSLocationUsageDescription

To understand geolocation errors, refer to this link

navigator.geolocation.getCurrentPosition(success => {
  /* Do some magic. */
}, failure => {
  if (failure.message.startsWith("Only secure origins are allowed")) {
    // Secure Origin issue.
  }
});

Include/set a "required_features" option within the manifest.webapp file:

{
  "required_features": ["geolocation"]
}

User:

On iPhone:

Settings -> Location Services -> [your Browser] [apple ref][1]

Chrome requires https for geolocation usage


Troubleshooting && Permissions Check / Debug Log

Ensure that both the OPERATING SYSTEM and BROWSER BOTH have location services enabled, and that the user's browser supports checking for location services

    // options for current position
    const navigatorLocationOptions = {
      enableHighAccuracy: true,
      timeout: 7000,
      maximumAge: 0
    };
 
    // does browser have geo services enabled
    navigator.permissions.query({name:'geolocation'})
      .then((result) => {
        
        if (result.state === 'granted') {// you are good
          navigator.geolocation.getCurrentPosition(position => {
             console.log('granted user location permission', position );
              
             //.. do your stuff

          }, (error) => {
            // OS services are not enabled
            console.log('Please turn on OS located services', navigator);
            errorLocation();
          }, navigatorLocationOptions);

        } else {
          // browser issues seriveces
          console.log('Browser location services disabled', navigator);
          errorLocation();
        }
      }, (error) => {
        /* Browser doesn't support querying for permissions */
        console.log('Please turn on BROWSER location services', navigator);
        errorLocation()
      }
    );


    //handle errors
    function errorLocation() {
      ...
    }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to handle waiting for an HTTP request to complete from a separate component?

https://i.sstatic.net/q4XYB.png An issue arises when calling the GetData function from a component's controller too early. I would like it to wait for the identification process to complete before triggering. During page loading, there is a server c ...

Innovative form creation using Vue.js

My interactive form allows users to input an item, quantity, and cost per item like this: <form @submit.prevent="submit"> <div class="form-group" v-for="(input,k) in inputs" :key="k"> <input ty ...

Seamless AJAX Uploads: Proceeding without pausing for a response

Currently, I am utilizing Blueimp's jQuery Uploader along with an S3 handler to successfully upload files and transfer them to S3 via the S3 API from the PHP SDK. While this setup works well, the issue arises when dealing with large files, particular ...

Executing tasks in a job on GitHub using Node.JS and .NET

I am currently in the process of developing a JavaScript API for a .NET project. In order to streamline my workflow, I would like to know if it is feasible to have GitHub actions set up with both Node.JS and various versions of .NET Core (2.1, 2.2, 3.0 or ...

Pass along computed style data to the parent component in Vue.js

I am relatively new to VueJS and currently in the process of exploring its features. One specific issue I am facing on my website involves a TopBar component that includes both the logo and the menu. <template> <div id="topBar"> <div ...

Arranging Check Boxes Side by Side

I am struggling to properly align the three checkboxes and tables next to each other. I have managed to get the checkboxes on the same row, but aligning them neatly has proven to be a challenge. Using Notepad++ as my development tool, I am facing formattin ...

Having trouble with *ngif not functioning properly after initial click in Angular 6

How do I create a Select field in Angular 6 that will hide or display another div based on the selected value? Below is the code snippet: <div class="form-group"> <label for="servicePriviledges">Managed</label> < ...

The mp3 file is not streaming at the moment, but there are no

I seem to be having trouble getting this file to play as an mp3. I can't pinpoint where I went wrong in my code. The println statement is being printed out, though. let mp3Url = "http://anything2mp3.com/system/files/mp3/Siberian%20Husky%20gets%20 ...

Manipulate the child elements within a list by altering their IDs with jQuery

I'm currently using jQuery to dynamically add options to a select tag from a dictionary. I now need to set the title attribute of each option based on the keys in the dictionary. Can anyone suggest a solution for this? JQuery function addOptions(){ ...

Can Big Data flow on Mongo DB be effectively simulated?

My idea involves creating a server with routes and models to be hosted on Heroku for processing requests. I plan to make incremental requests to the server until they qualify as Big Data. I suspect there may be limitations on how many consecutive requests ...

I'm sorry, but we were unable to locate the module: Error: Unable to find 'fs' in '/usr/src/app/node_modules/jpeg-exif/lib'

Encountering an error when building a react app on production: Module not found: Error: Can't resolve 'fs' in '/usr/src/app/node_modules/jpeg-exif/lib' Node Version: Node version 18 Steps taken in Docker Production: npm install - ...

When compiled on a device, Cordova is not utilizing CSS and JS files

I am currently in the process of developing an app using Cordova with an HTML file. However, after building the app, I encountered issues where it is not incorporating CSS and does not seem to be utilizing JavaScript. <!doctype html> <html la ...

"Using MKMapView to display custom pins offers dynamic changes in appearance as you zoom in and

I'm currently developing an application that utilizes MKMapView. The issue I am encountering is related to custom pins with images. Whenever I zoom in and then zoom out, the pins revert back to the default red color. Below is the snippet of code caus ...

A cautionary alert is triggered by vsCode when analyzing seemingly correct code sourced from vue.js documentation

While using Visual Studio Code version 1.13.1V and referring to the vue.js guide on lazy loading, I encountered an issue when writing the following code snippet: import Vue from 'vue' import Router from 'vue-router' const Health = () = ...

What is the best way to show an array within a string using javascript?

Take a look at this code snippet : const names = ["Alex", "John", "Kit", "Lenny"]; for(let i = 0; i < 4; i++) { $("body").append("<p>" + names[i] + "</p>'); }; Can you figure out how to dynamically add each item in the 'names&a ...

What happens when an iOS app surpasses the 100mb download limit in size?

Hello, I have been searching through various Apple forums to find out the maximum file size allowed for iOS apps. However, I have encountered conflicting information on this matter which is crucial for me to address in order to reduce the file size signifi ...

How can I add seconds to the jquery datetimepicker plugin?

Looking to implement the datetimepicker plugin from here, but I'm having trouble finding information on how to include the seconds part. Is there a way to add seconds to this plugin? It's a crucial requirement, so any suggestions for another good ...

Mastering the plutil command for arrays and strings: A comprehensive guide

I need to inject the following code into Info.plist file using Terminal: <key>SBAppTags</key> <array> <string>hidden</string> </array> Can someone provide me with the correct command line syntax to accomplish this? I ...

Running a function exported from a string in Node.js

Is it possible to execute a function with a name stored as a string in Node.js? The code is meant to run on the server side without any browser involvement. If I have a file named test.js exported with the following function: module.exports.test = functi ...

Sending data from JavaScript to PHP using hidden field

Despite my efforts to search online, I'm still confused. I am attempting to transfer the value of a counted radio button (in Javascript) to PHP using a hidden field which will then be inserted into a MySQL database. The form is named test.html. <h ...