Expo - How to get location permission specific data? - ios

I'm working with Expo SDK 42 and I'm having some problems retrieving specific data about the foreground location permission.
For ios, for example, when the user gets asked for permission, he gets 3 options: "allow once", "allow while using the app" or "don't allow".
The permission is being asked using the following method according to the documentation: requestForegroundPermissionsAsync(). So after requesting it, if the user selects "allow once" or "allow while using the app", that method will return exactly the same object, which contains a property telling that the permission is 'granted', and there's no difference in the return value if the user selected one option or the other.
The problem is, I need to know and differentiate if the user selected "allow once" or "allow while using the app" because, based on that, I will show a different screen.
Do you know if it's possible to do that with Expo? If not, is there a workaround or something I can do to know what option was selected by the user?
Thank you.

The short answer is it isn't possible to differentiate between "allow while using" and "allow once", and your app really shouldn't need to anyway. If the user selects "allow once" then your app will just ask for access again the next time it launches.
Essentially your app needs to handle three states:
Location access not determined
Location access granted
Location access denied.
Initially your app will have the not determined state. In response you request location access. If the user selects "allow" or "allow once" you will get an access granted state.
If they selected "allow once" then the status will return to "not determined" the next time your app launches and you need to ask again.
If they select "allow while using" or "deny" then that state is what your app will see on subsequent launches unless the user goes into the settings for your app and changes it.

Related

Xamarin Forms / Xamarin.Essentials - How to ensure that "Always Allow" Location permission has been granted from within the iOS app

I have a Xamarin Forms app running on iOS, which needs to receive location data even when not running in the foreground.
When the app first runs, the user is prompted to grant the location permission, from the options:
Allow "My App" to use your location?
Allow Once
Allow While Using App
Don't Allow
There is no "Always Allow" option.
If the user selects either "Allow Once", or "Allow While Using App", the app is able to retrieve the devices location, while in the foreground. All good so far.
If I then hit the device's Home button to remove focus from the app, leaving it to run in the background, I am prompted some (random amount of) time after with the iOS prompt:
Allow "My App" to also use your location even when you are not using the app?
Keep Only While Using
Change to Always Allow
If the user selects "Change to Always Allow", everything within the app works fine, including in the background. Just like I need it to.
However, from within the app, I want to do the following:
Rather than waiting an indeterminate/unknown amount of time for iOS to get around to prompting the user for the "Always Allow" permission, to ask iOS from within the app to prompt the user for the "Always Allow" permission when the app launches.
Check that the required "Always Allow" permission has been granted by the user.
Prompt the user for "Always Allow" permission
From within the app, I have tried the following code, but it doesn't seem to make any difference:
var permission = new Permissions.LocationAlways();
permission.EnsureDeclared();
Check that "Always Allow" Permission has been granted
From within the app, I am using the following code to check on the status of the LocationAlways permission.
But, even when the user has just granted "While using the app", and not yet been prompted for "Always Allow", the status of the LocationAlways permission still shows "Granted".
In fact, as far as I can tell, the following 2 lines of code always return the same status:
var locationAlwaysPermissionStatus = await Permissions.CheckStatusAsync<Permissions.LocationAlways>();
var locationWhenInUsePermissionStatus = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
Info.plist
These are the relevant entries from Info.plist.
<array>
<string>fetch</string>
<string>processing</string>
<string>location</string>
</array>
<key>NSLocationAlwaysUsageDescription</key>
<string>(Always message)</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>(Always and in use message)</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>(When in use message)</string>
I don't know if it's relevant, but I have had to include entries for all 3 message types, even though, as far as I am concerned, I am only interested in the Always usage.
NSLocationAlwaysUsageDescription
NSLocationAlwaysAndWhenInUseUsageDescription
NSLocationWhenInUseUsageDescription
When iOS initially prompts with the options "Allow Once / Allow While Using App / Don't Allow", it uses the "NSLocationWhenInUseUsageDescription" message.
...and when iOS eventually prompts the user to grant "Always Allow", it uses the "NSLocationAlwaysAndWhenInUseUsageDescription" message.
However, I also have to include "NSLocationAlwaysUsageDescription" in the Plist.info, although the message is never displayed, as without it, the app crashes when the app tries to call the "permission.EnsureDeclared()" method.
User can manually set the "Always Allow" location permission
I am aware that the user can manually enable the "Always Allow" permission in the app permissions. But, regardless, the app will need to know that the "Always Allow" location permission has indeed been granted, and not just the "While In Use" permission.
Can anyone offer any advice?

Solution for apple's objection&rejection on our GPS based app?

We are developing an app that share user location on the map when they login and others can tap on their profile pic on map and start chatting with them .
Apple rejected the app with following reply :
"17.1 - Apps cannot transmit data about a user without obtaining the user's prior permission and providing the user with access to information about how and where the data will be used.
Upon further review, we found that your app enables the display of nearby users’ locations on a map but only prompts users on sign up or sign in for permission to show their location. If the user has signed in and previously agreed, then they are not prompted again until they log out. This is not appropriate for the App Store.
Specifically, it is not appropriate to display the user's location automatically without the option to decline if they have already signed in to access your app." We already tried to add multiple popup/confirm boxes for user permissions. what should be done to take care of this privacy issue ?
Should we add a button to manually checkin , everytime they want to update thier location ? this will defeat the purpose though if they have to click a button to update location to show where they are .
Or
Should we ask for permission to Show location each time App is opened since apple's objection is that it don't ask for permission again untill user is logged out and log in back ?
This is a speculative answer, since Apple has somewhat fuzzy replies, but this is my view:
Specifically, it is not appropriate to display the user's location automatically without the option to decline if they have already signed in to access your app."
You could solve it by:
* Sending a push notification when the user's location is being used (this could be annoying depending on app usage of location)
* Showing some info in a very visible place in the app, e.g. in the lateral menu, along with the option to reject to share your location (or otherwise, tell the user there that they can do so by logging out)
There must be other possible solutions, since the reviewer is a human being and the guideline broad and unspecific enough... But I think any of these options would work.

iOS Location Services Alert - What is the delay between showing it?

Just a quick question here.
I am displaying the the alert for the user to allow the app to access location data, and I have this triggered from a switch.
When the user turns the switch on, the alert will be displayed.
If the user clicks disallow, is there a time restriction that Apple has before you can show that alert again?
Thanks in advance!
Once the user chooses not to give your app permission to access their location data, the user will not be able to grant your app that permission from within your app. Instead, the user must enter the Settings app and grant the permission from there. This is to prevent the app from bombarding the user with requests to use location data.

Request know their location after his deny it

I'm requesting know the user location (in an iOS App), but if he Deny it, I'm redirecting to other page, but this preference is stored in some place and the app is not requesting any more his location.
Exist a way to show again the popup requesting know the location again?
No, you only get one chance to ask for the users location.
Once that is done the user has to toggle it in the phone settings under "Location Services".

If an iOS consumer denies permission to 'Use Current Location', is it technically possible to show the permission dialogue again?

My iOS app wants to display the users current location. Nothing special - but to do so, the first time the app is ran (or more to the point, the first time an MKViewMap in the app is displayed, I guess...) .. the user is asked for permission (which is awesome).
eg.
Now, if the user accidentally says DON'T ALLOW or decides to (later on) give permission ... is there technically a way we can reset their previous decision and when the app is restarted, ask them again automatically when the MKViewMap is next rendered again?
The user can enable or disable that option in the setting of the iphone. To do this, user have to select the Privacy option in the Setting Menu, and then select the Location Services option and than search the desired app to whom user want to enable or disable the permission and perform desired function by switching the toggle button on or off.
As it was a Private API provided from Apple the alert cannot be shown up again. Alternatively, we can check manually and show an alert like this.
The following can be read in the Apple docs:
"...it is recommended that you always call the locationServicesEnabled class method of CLLocationManager before attempting to start either the standard or significant-change location services. If it returns NO and you attempt to start location services anyway, the system prompts the user to confirm whether location services should be re-enabled. Given that location services are very likely to be disabled on purpose, the user might not welcome this prompt."
If I understand it right the alert will pop up everytime you try to get the users location, but it's not recommended to do so.
Link to full post:
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html#//apple_ref/doc/uid/TP40009497-CH2-SW1
No you cannot do so. Rather than this, you can just check the latitude and longitude value and show alert to the user that enable the service from settings.

Resources