Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IOS getLocationAuthorizationStatus permissionStatus.GRANTED #454

Open
5 tasks done
golyo opened this issue Jan 19, 2022 · 2 comments
Open
5 tasks done

IOS getLocationAuthorizationStatus permissionStatus.GRANTED #454

golyo opened this issue Jan 19, 2022 · 2 comments
Labels
caveat A caveat of using this plugin ios relates to iOS platform

Comments

@golyo
Copy link

golyo commented Jan 19, 2022

Bug report

CHECKLIST

  • I have reproduced the issue using the example project or provided the necessary information to reproduce the issue.
  • I have checked that no similar issues (open or closed) already exist.

Current behavior:

After application deployed and started, I selected the 'Allow while using app' choice as location access on IOS.
The getLocationAuthorizationStatus returns permissionStatus.GRANTED, instead of permissionStatus.GRANTED_WHEN_IN_USE.
After I change to location mode maualy, the selected value will returns the right value to the getLocationAuthorizationStatus function.
But after deploy it is not woking properly.

Expected behavior:

The application should return permissionStatus.GRANTED_WHEN_IN_USE if I select the 'Allow while using app' at first time.

Steps to reproduce:

Screenshots

Environment information

  • Cordova CLI version : 10.0.0.
    • cordova -v
  • Cordova platform version: 6.1.1
    • cordova platform ls
  • Plugins & versions installed in project (including this plugin)
    • cordova plugin ls
  • Dev machine OS and version, e.g.
    • OSX: IOS 15, IOS 14, macbook IOS simulator
      • sw_vers
    • Windows 10
      • winver

Runtime issue

  • Device details
    • e.g. iPhone X, Samsung Galaxy S8, iPhone X Simulator, Pixel XL Emulator
  • OS details
    • e.g. iOS 12.2, Android 9.0

Android build issue:

  • Node JS version
    • node -v
  • Gradle version
    • ls platforms/android/.gradle
  • Target Android SDK version
    • android:targetSdkVersion in AndroidManifest.xml
  • Android SDK details
    • sdkmanager --list | sed -e '/Available Packages/q'

iOS build issue:

  • Node JS version
    • node -v 14.17.0
  • XCode version

Related code:

insert any relevant code here such as plugin API calls / input parameters

271797140_474468097421276_6049083327979679923_n-1

window.cordova.plugins.diagnostic.getLocationAuthorizationStatus((locationPermission) => {
  console.log(`Location permission setting is ${locationPermission}`);
}, (err) => {
  console.error('Error', err);
});

Console output
Location permission setting is granted

console output

// Paste any relevant JS/native console output here



Other information:

@spoxies
Copy link

spoxies commented Mar 28, 2022

I have not tested this (it is a theory), but with newer iOS versions there might be some magic going on within iOS itself where it has changed the API but tries to stay semi backwards compatible. Meaning that when you initially request cordova.plugins.diagnostic.locationAuthorizationMode.ALWAYS it will actually ask the user for permission cordova.plugins.diagnostic.locationAuthorizationMode.WHEN_IN_USE.

Once [...].WHEN_IN_USE is granted you can request [...].ALWAYS. But that is not the end because it will ask the user later on or re-request to change in [...].ALWAYS . Anyway since the API changed I wonder if the behaviour you describe still occurs if you (correctly) request [...].WHEN_IN_USE instead of [...].ALWAYS when the app is started/installed initially. Because the actual grant level might be in some limbo state within iOS itself.

cordova.plugins.diagnostic.requestLocationAuthorization(function(status){
    console.log(status);
}, function(error){
    console.error(error);
}, cordova.plugins.diagnostic.locationAuthorizationMode.WHEN_IN_USE);

@dpa99c
Copy link
Owner

dpa99c commented Jul 25, 2022

This is a quirk of the iOS Location Manager behaviour of iOS 14+

If you request location permission ALWAYS:

cordova.plugins.diagnostic.requestLocationAuthorization
	handleSuggest, 
	handleError, 
	cordova.plugins.diagnostic.locationAuthorizationMode.ALWAYS
);

Then select "Allow While Using App" in permission dialog, iOS invokes the locationManagerDidChangeAuthorization delegate method with authorization status kCLAuthorizationStatusAuthorizedAlways.

The plugin then maps this constant to the GRANTED string value.

Conversely, if you request permission ALWAYS and you select "Allow Once" in the permission dialog, locationManagerDidChangeAuthorization will be invoked with authorization status constant kCLAuthorizationStatusAuthorizedWhenInUse which this plugin maps to GRANTED_WHEN_IN_USE.

For comparison, if you request WHEN_IN_USE permission and select "Allow Once", locationManagerDidChangeAuthorization will be invoked with authorization status constant kCLAuthorizationStatusAuthorizedWhenInUse.
And if you request WHEN_IN_USE permission and select "Allow While Using App", the result is also kCLAuthorizationStatusAuthorizedWhenInUse.

Just to be clear, here are those results in tabular form:

Permission requested User choice Native constant Plugin constant
ALWAYS Allow While Using App kCLAuthorizationStatusAuthorizedAlways GRANTED
ALWAYS Allow Once kCLAuthorizationStatusAuthorizedWhenInUse GRANTED_WHEN_IN_USE
WHEN_IN_USE Allow While Using App kCLAuthorizationStatusAuthorizedWhenInUse GRANTED_WHEN_IN_USE
WHEN_IN_USE Allow Once kCLAuthorizationStatusAuthorizedWhenInUse GRANTED_WHEN_IN_USE

It really does seem like Apple has got this backwards as you'd expect having requested location ALWAYS that "Allow While Using App" would result in kCLAuthorizationStatusAuthorizedWhenInUse and Allow Once would result in kCLAuthorizationStatusAuthorizedAlways.

I guess the plugin could "remember" that you'd requested ALWAYS permission and then invert the resulting permission status in locationManagerDidChangeAuthorization but this would mean the plugin would then not be reflecting the actual native constant being return by the location manager.

Therefore it's probably best that you handle this anomalous behaviour with your own logic at app-level.

@dpa99c dpa99c added caveat A caveat of using this plugin ios relates to iOS platform labels Jul 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
caveat A caveat of using this plugin ios relates to iOS platform
Projects
None yet
Development

No branches or pull requests

3 participants