Flint icon indicating copy to clipboard operation
Flint copied to clipboard

Better handling of unsupported permissions in development

Open marcpalmer opened this issue 6 years ago • 2 comments

There are some times where things can seem to fail silently, such as requesting permissions for a feature where some of the permissions are simply not supported on the platform. We need to always output information about this for the developer to throw them a bone when things are going wrong.

For example, a feature that requires Calendar access but the app has not imported EventKit will result in that feature never being available and permission never being requested.

In this example:

            if let adapter = adapterType {
                if adapter.isSupported {
                    // We probably need to also verify there is actual camera hardware, e.g. WatchOS
                    add(adapter.createAdapters(for: permission))
                } else {
                    FlintInternal.logger?.warning("Permission \(permission) is not supported. Either the target platform does not implement it, or your target is not linking the framework required.")
                }
            }

This is actually tricky. Flint logging may be disabled, and we still need to output this info in dev mode.

Also, however, it may be that the feature simply cannot run at all on the target platform, in which case there is no point in requesting permissions, it should always just fail fast and the authorisation controller process needs to pick up on this and not prompt for anything, and always leave it unfulfilled.

We also probably need to look at .unsupported on SystemPermissionStatus ... is this needed if isSupported gates access to this? How can the authorisation controller easily tell whether or not there are any unsupported permissions on the current platform, and short circuit permissions checks.

Should the .notDetermined set of permissions on a feature not even include unsupported permissions, as this would prevent the auth controller from requesting anything and still prevent the feature from being used.

marcpalmer avatar Jul 11 '18 09:07 marcpalmer

The thinking in the above that having unsupported permissions is fine - you want to be able to write cross platform code that can test if a feature is enabled, without worrying about platform specifics. e.g. a data store might test if the calendar cloud sync feature is enabled, and that requires calendars access, but maybe your app on watchOS doesn't link EventKit deliberately, yet shares this code that would otherwise have to have a bunch of compile time checks added to it.

marcpalmer avatar Jul 11 '18 09:07 marcpalmer

One possible simple solution here, as this is dev information only, is to change flintAdvistoryNotice to always use print() in dev builds so it cannot be suppressed accidentally by turning off logging, and change all isSupported implementations to use it to output the reason why the permission is not supported if indeed it isn't. Change isSupported to availability and return type to an enum with .supported, and .notLinked(framework:), .unsupported so that we have this logging in one place (DefaultPermissionChecker) and they can return reasons like "EventKit is not linked and we can provide better information

marcpalmer avatar Jul 11 '18 09:07 marcpalmer