Currently Xamarin.Essentials prompts users for permissions when needed for specific APIs and will throw a permissions exception if the user denies it. There is no current implementation for developers to check permission status and attempt to prompt themselves.
I have a permissions plugin: https://github.com/jamesmontemagno/PermissionsPlugin however I would say that this implementation is not perfect and using an enum for permission is not super ideal because some permissions require objects to be saved around and require info.plist because it isn't super linker safe :(
The recommendation is to enable developers to check and request permissions for the APIs that we have and not attempt to do a generic one. Some thoughts here are to have them be async or should we actually move towards an event based architecture, which is what each platform uses.
Here is what I would do for Android today:
Status:
/// <summary>
/// Status of a permission
/// </summary>
public enum PermissionStatus
{
/// <summary>
/// Denied by user
/// </summary>
Denied,
/// <summary>
/// Feature is disabled on device
/// </summary>
Disabled,
/// <summary>
/// Granted by user
/// </summary>
Granted,
/// <summary>
/// Restricted (only iOS)
/// </summary>
Restricted,
/// <summary>
/// Permission is in an unknown state
/// </summary>
Unknown
}
public static class FlashlightPermission
{
Task<PermissionStatus> CheckStatusAsync();
Task<PermissionStatus> RequestAsync();
}
public static class LocationWhenInUsePermission
{
Task<PermissionStatus> CheckStatusAsync();
Task<PermissionStatus> RequestAsync();
}
These two would handle the permissions that are currently used in Xamarin.Essentials
VS bug #735658
We could also just include the permission checks in the API:
public static partial class Flashlight {
// existing code
public static Task TurnOnAsync();
public static Task TurnOffAsync();
// new code
Task<PermissionStatus> CheckPermissionStatusAsync();
Task<PermissionStatus> RequestPermissionAsync();
}
This will keep all the flashlight bits together, and reduce the number of types.
Could work out if we standardize this way. We just need to document when we need to call these.
I believe if we keep the functionality in each class small and container then it works out nice.
Perhaps not add a generic API at all and just how you have it.
This is great API to be added to Xamarin Essential but just one note.. you should have:
Permission for Use Location when app is running
Permission for Always use location
As separate functions
I would actually love if this were a distinct type. While we currently might only expose permissions needed by XE we might in the future add support for requesting more Permissions than directly accessable via our Types. This would be impossible if we couple Permissions with our types.
The interesting thing with Permissions is Android is pretty loose around what a permission is (it can basically be any string) but iOS is rigid in what permissions exist.
We are going to add support for managing permissions in a general way, not just those that are required by Xamarin.Essentials (which we still want to keep managing the way we do - probably with the Permissions api that we eventually make public).
Is this issue currently still in discussion?
Good question. When will this be implemented and what should we use? Xamarin.Essentials or the PermissionsPlugin?
Currently, I want to request Location from infrastructure Service class, but if this code from service is running in background thread and app does not have permission granted, Xamarin.Essentials will ask for permission and throw an Exception (because of background thread) -> so I am forced to:
add some try/catch handling to all platform specific features which requires permissions, because I do not have control how and when Xamarin.Essentials will ask for permissions
implement permissions handling by myself, currently in ViewModel before invoking code of Service class, I ask user for permissions with help of Permissions.Plugin -> this is doubling permission handling code in app, adds another nugget package to achieve same behavior as the first one
I really appreciate to have new Xamarin.Essentials APIs for Permissions handling or make public permissions API which is used in Xamarin.Essentials.
And for platform specific code which needs some permissions there could be optional flag for disabling permissions handling by default.
For example Location request could look like this:
await Geolocation.GetLocationAsync(request, disablePermissionsHandling: true);
With following changes in API:
public static Task<Location> GetLocationAsync(GeolocationRequest request, bool disablePermissionsHandling = false );
PS. I really want to keep separated UI and Logic in my application, so displaying user dialog from deep parts of the logic of my application is not ideal.
Officially integrated into 1.4.0-pre
Most helpful comment
Is this issue currently still in discussion?