Commit c3f0f8d8 by Maurits van Beusekom Committed by GitHub

Merge pull request #421 from MathiasCochet/develop

iOS 14 update for photos permission
parents 3386174f 436b865c
...@@ -63,7 +63,7 @@ final class PermissionConstants { ...@@ -63,7 +63,7 @@ final class PermissionConstants {
static final int PERMISSION_STATUS_GRANTED = 1; static final int PERMISSION_STATUS_GRANTED = 1;
static final int PERMISSION_STATUS_RESTRICTED = 2; static final int PERMISSION_STATUS_RESTRICTED = 2;
static final int PERMISSION_STATUS_NOT_DETERMINED = 3; static final int PERMISSION_STATUS_NOT_DETERMINED = 3;
static final int PERMISSION_STATUS_NEVER_ASK_AGAIN = 4; static final int PERMISSION_STATUS_NEVER_ASK_AGAIN = 5;
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef({ @IntDef({
......
...@@ -37,6 +37,8 @@ class _PermissionState extends State<PermissionWidget> { ...@@ -37,6 +37,8 @@ class _PermissionState extends State<PermissionWidget> {
return Colors.red; return Colors.red;
case PermissionStatus.granted: case PermissionStatus.granted:
return Colors.green; return Colors.green;
case PermissionStatus.limited:
return Colors.orange;
default: default:
return Colors.grey; return Colors.grey;
} }
......
...@@ -54,6 +54,13 @@ ...@@ -54,6 +54,13 @@
#define PERMISSION_PHOTOS 1 #define PERMISSION_PHOTOS 1
#endif #endif
// ios: PermissionGroupPhotosAddOnly
// Info.plist: NSPhotoLibraryUsageDescription
// dart: PermissionGroup.photosAddOnly
#ifndef PERMISSION_PHOTOS_ADD_ONLY
#define PERMISSION_PHOTOS_ADD_ONLY
#endif
// ios: [PermissionGroupLocation, PermissionGroupLocationAlways, PermissionGroupLocationWhenInUse] // ios: [PermissionGroupLocation, PermissionGroupLocationAlways, PermissionGroupLocationWhenInUse]
// Info.plist: [NSLocationUsageDescription, NSLocationAlwaysAndWhenInUseUsageDescription, NSLocationWhenInUseUsageDescription] // Info.plist: [NSLocationUsageDescription, NSLocationAlwaysAndWhenInUseUsageDescription, NSLocationWhenInUseUsageDescription]
// dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse] // dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
...@@ -92,6 +99,7 @@ typedef NS_ENUM(int, PermissionGroup) { ...@@ -92,6 +99,7 @@ typedef NS_ENUM(int, PermissionGroup) {
PermissionGroupMicrophone, PermissionGroupMicrophone,
PermissionGroupPhone, PermissionGroupPhone,
PermissionGroupPhotos, PermissionGroupPhotos,
PermissionGroupPhotosAddOnly,
PermissionGroupReminders, PermissionGroupReminders,
PermissionGroupSensors, PermissionGroupSensors,
PermissionGroupSms, PermissionGroupSms,
...@@ -108,6 +116,7 @@ typedef NS_ENUM(int, PermissionStatus) { ...@@ -108,6 +116,7 @@ typedef NS_ENUM(int, PermissionStatus) {
PermissionStatusGranted, PermissionStatusGranted,
PermissionStatusRestricted, PermissionStatusRestricted,
PermissionStatusNotDetermined, PermissionStatusNotDetermined,
PermissionStatusLimited,
}; };
typedef NS_ENUM(int, ServiceStatus) { typedef NS_ENUM(int, ServiceStatus) {
......
...@@ -102,7 +102,9 @@ ...@@ -102,7 +102,9 @@
case PermissionGroupPhone: case PermissionGroupPhone:
return [PhonePermissionStrategy new]; return [PhonePermissionStrategy new];
case PermissionGroupPhotos: case PermissionGroupPhotos:
return [PhotoPermissionStrategy new]; return [[PhotoPermissionStrategy alloc] initWithAccessAddOnly:false];
case PermissionGroupPhotosAddOnly:
return [[PhotoPermissionStrategy alloc] initWithAccessAddOnly:true];
case PermissionGroupReminders: case PermissionGroupReminders:
return [EventPermissionStrategy new]; return [EventPermissionStrategy new];
case PermissionGroupSensors: case PermissionGroupSensors:
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#import <Photos/Photos.h> #import <Photos/Photos.h>
@interface PhotoPermissionStrategy : NSObject <PermissionStrategy> @interface PhotoPermissionStrategy : NSObject <PermissionStrategy>
-(instancetype)initWithAccessAddOnly:(BOOL) addOnly;
@end @end
#else #else
......
...@@ -7,9 +7,21 @@ ...@@ -7,9 +7,21 @@
#if PERMISSION_PHOTOS #if PERMISSION_PHOTOS
@implementation PhotoPermissionStrategy @implementation PhotoPermissionStrategy{
bool addOnlyAccessLevel;
}
- (instancetype)initWithAccessAddOnly:(BOOL)addOnly {
self = [super init];
if(self) {
addOnlyAccessLevel = addOnly;
}
return self;
}
- (PermissionStatus)checkPermissionStatus:(PermissionGroup)permission { - (PermissionStatus)checkPermissionStatus:(PermissionGroup)permission {
return [PhotoPermissionStrategy permissionStatus]; return [PhotoPermissionStrategy permissionStatus:addOnlyAccessLevel];
} }
- (ServiceStatus)checkServiceStatus:(PermissionGroup)permission { - (ServiceStatus)checkServiceStatus:(PermissionGroup)permission {
...@@ -24,13 +36,24 @@ ...@@ -24,13 +36,24 @@
return; return;
} }
if(@available(iOS 14, *)) {
[PHPhotoLibrary requestAuthorizationForAccessLevel:(addOnlyAccessLevel)?PHAccessLevelAddOnly:PHAccessLevelReadWrite handler:^(PHAuthorizationStatus authorizationStatus) {
completionHandler([PhotoPermissionStrategy determinePermissionStatus:authorizationStatus]);
}];
}else {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus authorizationStatus) { [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus authorizationStatus) {
completionHandler([PhotoPermissionStrategy determinePermissionStatus:authorizationStatus]); completionHandler([PhotoPermissionStrategy determinePermissionStatus:authorizationStatus]);
}]; }];
}
} }
+ (PermissionStatus)permissionStatus { + (PermissionStatus)permissionStatus:(BOOL) addOnlyAccessLevel {
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus]; PHAuthorizationStatus status;
if(@available(iOS 14, *)){
status = [PHPhotoLibrary authorizationStatusForAccessLevel:(addOnlyAccessLevel)?PHAccessLevelAddOnly:PHAccessLevelReadWrite];
}else {
status = [PHPhotoLibrary authorizationStatus];
}
return [PhotoPermissionStrategy determinePermissionStatus:status]; return [PhotoPermissionStrategy determinePermissionStatus:status];
} }
...@@ -45,6 +68,8 @@ ...@@ -45,6 +68,8 @@
return PermissionStatusDenied; return PermissionStatusDenied;
case PHAuthorizationStatusAuthorized: case PHAuthorizationStatusAuthorized:
return PermissionStatusGranted; return PermissionStatusGranted;
case PHAuthorizationStatusLimited:
return PermissionStatusLimited;
} }
return PermissionStatusNotDetermined; return PermissionStatusNotDetermined;
......
...@@ -23,8 +23,8 @@ Future<bool> openAppSettings() => _handler.openAppSettings(); ...@@ -23,8 +23,8 @@ Future<bool> openAppSettings() => _handler.openAppSettings();
/// Actions that can be executed on a permission. /// Actions that can be executed on a permission.
extension PermissionActions on Permission { extension PermissionActions on Permission {
/// The current status of this permission. /// The current status of this permission.
/// ///
/// The Android-only [PermissionStatus.permanentlyDenied] status will only be /// The Android-only [PermissionStatus.permanentlyDenied] status will only be
/// calculated if the active context is an Activity. If it isn't, /// calculated if the active context is an Activity. If it isn't,
/// [PermissionStatus.denied] will be returned. /// [PermissionStatus.denied] will be returned.
Future<PermissionStatus> get status => _handler.checkPermissionStatus(this); Future<PermissionStatus> get status => _handler.checkPermissionStatus(this);
...@@ -67,6 +67,10 @@ extension PermissionCheckShortcuts on Permission { ...@@ -67,6 +67,10 @@ extension PermissionCheckShortcuts on Permission {
/// *Only supported on iOS.* /// *Only supported on iOS.*
Future<bool> get isRestricted => status.isRestricted; Future<bool> get isRestricted => status.isRestricted;
///User has authorized this application for limited photo library access.
/// *Only supported on iOS.(iOS14+)*
Future<bool> get isLimited => status.isLimited;
/// If the user denied this permission and selected to never again show a /// If the user denied this permission and selected to never again show a
/// request for it. The user may still change the permission's status in the /// request for it. The user may still change the permission's status in the
/// device settings. /// device settings.
......
...@@ -16,7 +16,10 @@ dependencies: ...@@ -16,7 +16,10 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
meta: ^1.1.6 meta: ^1.1.6
permission_handler_platform_interface: ^2.0.1 permission_handler_platform_interface:
git:
url: https://github.com/MathiasCochet/flutter-permission-handler.git
path: permission_handler_platform_interface
dev_dependencies: dev_dependencies:
effective_dart: ^1.2.1 effective_dart: ^1.2.1
......
...@@ -17,6 +17,10 @@ enum PermissionStatus { ...@@ -17,6 +17,10 @@ enum PermissionStatus {
/// *Only supported on iOS.* /// *Only supported on iOS.*
restricted, restricted,
///User has authorized this application for limited access.
/// *Only supported on iOS (iOS14+).*
limited,
/// The user denied access to the requested feature and selected to never /// The user denied access to the requested feature and selected to never
/// again show a request for this permission. The user may still change the /// again show a request for this permission. The user may still change the
/// permission status in the settings. /// permission status in the settings.
...@@ -36,6 +40,8 @@ extension PermissionStatusValue on PermissionStatus { ...@@ -36,6 +40,8 @@ extension PermissionStatusValue on PermissionStatus {
case PermissionStatus.undetermined: case PermissionStatus.undetermined:
return 3; return 3;
case PermissionStatus.permanentlyDenied: case PermissionStatus.permanentlyDenied:
return 5;
case PermissionStatus.limited:
return 4; return 4;
default: default:
throw UnimplementedError(); throw UnimplementedError();
...@@ -48,6 +54,7 @@ extension PermissionStatusValue on PermissionStatus { ...@@ -48,6 +54,7 @@ extension PermissionStatusValue on PermissionStatus {
PermissionStatus.granted, PermissionStatus.granted,
PermissionStatus.restricted, PermissionStatus.restricted,
PermissionStatus.undetermined, PermissionStatus.undetermined,
PermissionStatus.limited,
PermissionStatus.permanentlyDenied, PermissionStatus.permanentlyDenied,
][value]; ][value];
} }
...@@ -74,6 +81,8 @@ extension PermissionStatusGetters on PermissionStatus { ...@@ -74,6 +81,8 @@ extension PermissionStatusGetters on PermissionStatus {
/// permission status in the settings. /// permission status in the settings.
/// *Only supported on Android.* /// *Only supported on Android.*
bool get isPermanentlyDenied => this == PermissionStatus.permanentlyDenied; bool get isPermanentlyDenied => this == PermissionStatus.permanentlyDenied;
bool get isLimited => this == PermissionStatus.limited;
} }
extension FuturePermissionStatusGetters on Future<PermissionStatus> { extension FuturePermissionStatusGetters on Future<PermissionStatus> {
...@@ -98,4 +107,6 @@ extension FuturePermissionStatusGetters on Future<PermissionStatus> { ...@@ -98,4 +107,6 @@ extension FuturePermissionStatusGetters on Future<PermissionStatus> {
/// *Only supported on Android.* /// *Only supported on Android.*
Future<bool> get isPermanentlyDenied async => Future<bool> get isPermanentlyDenied async =>
(await this).isPermanentlyDenied; (await this).isPermanentlyDenied;
Future<bool> get isLimited async => (await this).isLimited;
} }
...@@ -55,47 +55,53 @@ class Permission { ...@@ -55,47 +55,53 @@ class Permission {
/// Android: Nothing /// Android: Nothing
/// iOS: Photos /// iOS: Photos
/// iOS 14+ read & write access level
static const photos = Permission._(9); static const photos = Permission._(9);
/// Android: Nothing /// Android: Nothing
/// iOS: Photos
/// iOS 14+ read & write access level
static const photosAddOnly = Permission._(10);
/// Android: Nothing
/// iOS: Reminders /// iOS: Reminders
static const reminders = Permission._(10); static const reminders = Permission._(11);
/// Android: Body Sensors /// Android: Body Sensors
/// iOS: CoreMotion /// iOS: CoreMotion
static const sensors = Permission._(11); static const sensors = Permission._(12);
/// Android: Sms /// Android: Sms
/// iOS: Nothing /// iOS: Nothing
static const sms = Permission._(12); static const sms = Permission._(13);
/// Android: Microphone /// Android: Microphone
/// iOS: Speech /// iOS: Speech
static const speech = Permission._(13); static const speech = Permission._(14);
/// Android: External Storage /// Android: External Storage
/// iOS: Access to folders like `Documents` or `Downloads`. Implicitly /// iOS: Access to folders like `Documents` or `Downloads`. Implicitly
/// granted. /// granted.
static const storage = Permission._(14); static const storage = Permission._(15);
/// Android: Ignore Battery Optimizations /// Android: Ignore Battery Optimizations
static const ignoreBatteryOptimizations = Permission._(15); static const ignoreBatteryOptimizations = Permission._(16);
/// Android: Notification /// Android: Notification
/// iOS: Notification /// iOS: Notification
static const notification = Permission._(16); static const notification = Permission._(17);
/// Android: Allows an application to access any geographic locations /// Android: Allows an application to access any geographic locations
/// persisted in the user's shared collection. /// persisted in the user's shared collection.
static const accessMediaLocation = Permission._(17); static const accessMediaLocation = Permission._(18);
/// When running on Android Q and above: Activity Recognition /// When running on Android Q and above: Activity Recognition
/// When running on Android < Q: Nothing /// When running on Android < Q: Nothing
/// iOS: Nothing /// iOS: Nothing
static const activityRecognition = Permission._(18); static const activityRecognition = Permission._(19);
/// The unknown only used for return type, never requested /// The unknown only used for return type, never requested
static const unknown = Permission._(19); static const unknown = Permission._(20);
/// Returns a list of all possible [PermissionGroup] values. /// Returns a list of all possible [PermissionGroup] values.
static const List<Permission> values = <Permission>[ static const List<Permission> values = <Permission>[
...@@ -109,6 +115,7 @@ class Permission { ...@@ -109,6 +115,7 @@ class Permission {
microphone, microphone,
phone, phone,
photos, photos,
photosAddOnly,
reminders, reminders,
sensors, sensors,
sms, sms,
...@@ -132,6 +139,7 @@ class Permission { ...@@ -132,6 +139,7 @@ class Permission {
'microphone', 'microphone',
'phone', 'phone',
'photos', 'photos',
'photosAddOnly',
'reminders', 'reminders',
'sensors', 'sensors',
'sms', 'sms',
......
...@@ -3,7 +3,7 @@ description: A common platform interface for the permission_handler plugin. ...@@ -3,7 +3,7 @@ description: A common platform interface for the permission_handler plugin.
homepage: https://github.com/baseflow/flutter-permission-handler/tree/master/permission_handler_platform_interface homepage: https://github.com/baseflow/flutter-permission-handler/tree/master/permission_handler_platform_interface
# NOTE: We strongly prefer non-breaking changes, even at the expense of a # NOTE: We strongly prefer non-breaking changes, even at the expense of a
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
version: 2.0.1 version: 2.0.2
dependencies: dependencies:
flutter: flutter:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment