user11701404
user11701404

Reputation:

getCurrentPosition in JS does not work on iOS

I have a page that contains a code that gets the current location from the device and load other stuff based on the location with this code:

if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(successFunction);
} else {
    // Make API call to the GeoIP services
}

It works on all android devices that I tested, but on iOS and macOS, it’s not working. Neither if nor else. Seems like it stuck at getting the current location.

Any help?

Upvotes: 13

Views: 19227

Answers (4)

Tony Brasunas
Tony Brasunas

Reputation: 4592

You need to check three things

Here's what you need to check to understand why your procedure does not have access to the user's location. Your code should ensure these three things:

  1. The user's Operating System has location services enabled.
  2. The user's browser supports checking for location services.
  3. The user's browser has location services enabled.

Combining the answers on the page and one additional check, we can handle all three of these scenarios:

    /* Set up getCurrentPosition options with a timeout */
    const navigatorLocationOptions = {
      enableHighAccuracy: true,
      timeout: 5000,
      maximumAge: 0
    };

    /* Determine browser permissions status */
    navigator.permissions.query({name:'geolocation'})
      .then((result) => {
        /* result.state will be 'granted', 'denied', or 'error' */
        if (result.state === 'granted') {
          navigator.geolocation.getCurrentPosition(pos => {
             console.log('Retrieved user location', pos);
             /* Got the location! Write your successful code here. */            

          }, (error) => {
            /* System/OS location services disabled */
            console.log('System/OS services disabled', navigator);
            noLocationFound();
          }, navigatorLocationOptions);

        } else {
          /* Browser location services disabled or error */
          console.log('Browser location services disabled', navigator);
          noLocationFound();
        }
      }, (error) => {
        /* Browser doesn't support querying for permissions */
        console.log('Browser permissions services unavailable', navigator);
        noLocationFound()
      }
    );
    
    /* Handle no location found */
    function noLocationFound() {
      /* Write code here to handle: user location is unavailable */
    }

Simply add your handling code for user notification and fallback in the noLocationFound() function.

Upvotes: 5

Tahir Hussain Mir
Tahir Hussain Mir

Reputation: 2626

I just encountered the same issue. The simple answer is to ask the user, to give the permission to your browser in

Settings > Privacy > Location Services.

Upvotes: 0

Mojtaba Hosseini
Mojtaba Hosseini

Reputation: 119292

iOS and macOS doesn't give you the user's location if they don't allow it or if the system can not trust you. So:

- First (Probably your answer)

It works with the exact code you provided ONLY IF the host (aka the origin) is using https. That is the cause of permission alert not showing up due to your comment to an answer below.

Remember if you not use https, it will be stuck for about a minute and then returns an error about authentication failure. Use error to check that:

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

It will tell you something like this:

[blocked] Access to geolocation was blocked over insecure connection to http://example.com.

Tip: You can refresh the page after you requested the location to skip the waiting process. But don't forget to check the Preserve Log option in the inspector.

- Second:

If you are using https, then check your location settings for Safari, which might have been set to OFF somehow, you can change it here: Settings > Privacy > Location Services > Safari. This is not the default option, but maybe you changed it accidentally. So don't worry about the users if this was the issue. And if you use Chrome or any other third party browsers, head to its settings and check for location access. It's not there by default and appears only if location wanted at least once.

- Third:

If you are about to load your web inside an app using webView, make sure to add location permission descriptions to the info.plist file. Add NSLocationWhenInUseUsageDescription versus NSLocationAlwaysUsageDescription versus NSLocationUsageDescription as your needs.

For the sake of completeness, on iOS13, you can not get always permission. But this is not the point here and the point is you have to get the required permissions sometime before you need to get the location from GPS or it is not going to work at all.

Upvotes: 19

Viacheslav Moskalenko
Viacheslav Moskalenko

Reputation: 1067

GeoLocation works only if a user provides his/her permissions.

Make sure that is the case.

This CodePen demo has been tested in iOS simulator with Safari and successfully shown the latitude and the longitude.

enter image description here

var options = {
  enableHighAccuracy: true,
  timeout: 5000,
  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);

It can't be the case if your code doesn't hit either if nor else unless some other code has triggered an infinite loop earlier in your code.

Upvotes: 2

Related Questions