Skip to content

Commit

Permalink
Merge branch 'main' into patch-2
Browse files Browse the repository at this point in the history
  • Loading branch information
mvanbeusekom authored Mar 26, 2024
2 parents 0c222fd + 59fee21 commit 234c5f9
Show file tree
Hide file tree
Showing 29 changed files with 132 additions and 39 deletions.
21 changes: 20 additions & 1 deletion permission_handler_apple/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
## 9.4.4

* Fixes typo in comment for full calendar access.

## 9.4.3

* Adds the `PERMISSION_LOCATION_WHENINUSE` macro, which can be used instead of
the `PERMISSION_LOCATION` macro, and exclusively enables the `requestWhenInUseAuthorization`
and remove the `requestAlwaysAuthorization` when requesting location permission.
* Improves error handling when `Info.plist` doesn't contain the correct declarations.
* Adds support for the `NSLocationAlwaysAndWhenInUseUsageDescription` property list
key.

## 9.4.2

* Updates the privacy manifest to include the use of the `NSUserDefaults` API.
The permission_handler stores a boolean value to track if permission to always
access the device location has been requested.

## 9.4.1

* Fix typo in comment for full calendar access.
* Adds empty privacy manifest.

## 9.4.0

Expand Down
5 changes: 5 additions & 0 deletions permission_handler_apple/example/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,13 @@ post_install do |installer|
## dart: PermissionGroup.photos
'PERMISSION_PHOTOS=1',

## The 'PERMISSION_LOCATION' macro enables the `locationWhenInUse` and `locationAlways` permission. If
## the application only requires `locationWhenInUse`, only specify the `PERMISSION_LOCATION_WHENINUSE`
## macro.
##
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
'PERMISSION_LOCATION=1',
'PERMISSION_LOCATION_WHENINUSE=0',

## dart: PermissionGroup.notification
'PERMISSION_NOTIFICATIONS=1',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
D38B08CB85942E5D11545EE3 /* [CP] Embed Pods Frameworks */,
A7B07F67421488A414C73AAD /* [CP] Copy Pods Resources */,
);
buildRules = (
);
Expand All @@ -157,7 +158,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1430;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
Expand Down Expand Up @@ -252,6 +253,23 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
A7B07F67421488A414C73AAD /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
D38B08CB85942E5D11545EE3 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
}

self->_methodResult = nil;
}];
} errorHandler:^(NSString *errorCode, NSString *errorDescription) {
self->_methodResult([FlutterError errorWithCode:errorCode message:errorDescription details:nil]);
self->_methodResult = nil;
}
];

} else if ([@"shouldShowRequestPermissionRationale" isEqualToString:call.method]) {
result(@false);
Expand Down
2 changes: 1 addition & 1 deletion permission_handler_apple/ios/Classes/PermissionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ typedef void (^PermissionRequestCompletion)(NSDictionary *permissionRequestResul
@interface PermissionManager : NSObject

- (instancetype)initWithStrategyInstances;
- (void)requestPermissions:(NSArray *)permissions completion:(PermissionRequestCompletion)completion;
- (void)requestPermissions:(NSArray *)permissions completion:(PermissionRequestCompletion)completion errorHandler:(PermissionErrorHandler)errorHandler;

+ (void)checkPermissionStatus:(enum PermissionGroup)permission result:(FlutterResult)result;
+ (void)checkServiceStatus:(enum PermissionGroup)permission result:(FlutterResult)result;
Expand Down
14 changes: 8 additions & 6 deletions permission_handler_apple/ios/Classes/PermissionManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ + (void)checkServiceStatus:(enum PermissionGroup)permission result:(FlutterResul
}];
}

- (void)requestPermissions:(NSArray *)permissions completion:(PermissionRequestCompletion)completion {
- (void)requestPermissions:(NSArray *)permissions completion:(PermissionRequestCompletion)completion errorHandler:(PermissionErrorHandler)errorHandler {
NSMutableDictionary *permissionStatusResult = [[NSMutableDictionary alloc] init];

if (permissions.count == 0) {
Expand All @@ -57,22 +57,24 @@ - (void)requestPermissions:(NSArray *)permissions completion:(PermissionRequestC
__block id <PermissionStrategy> permissionStrategy = [PermissionManager createPermissionStrategy:permission];
[_strategyInstances addObject:permissionStrategy];


[permissionStrategy requestPermission:permission completionHandler:^(PermissionStatus permissionStatus) {
permissionStatusResult[@(permission)] = @(permissionStatus);
[requestQueue removeObject:@(permission)];

[self->_strategyInstances removeObject:permissionStrategy];

if (requestQueue.count == 0) {
completion(permissionStatusResult);
}

// Make sure `completion` is called before cleaning up the reference
// otherwise the `completion` block is also dereferenced on iOS 12 and
// below (this is most likely a bug in Objective-C which is solved in
// later versions of the runtime).
permissionStrategy = nil;
} errorHandler: ^(NSString* errorCode, NSString* errorDesciption) {
errorHandler(errorCode, errorDesciption);
permissionStrategy = nil;
}];
}
}
Expand Down Expand Up @@ -108,7 +110,7 @@ + (id)createPermissionStrategy:(PermissionGroup)permission {
case PermissionGroupLocation:
case PermissionGroupLocationAlways:
case PermissionGroupLocationWhenInUse:
#if PERMISSION_LOCATION
#if PERMISSION_LOCATION || PERMISSION_LOCATION_WHENINUSE || PERMISSION_LOCATION_ALWAYS
return [[LocationPermissionStrategy alloc] initWithLocationManager];
#else
return [LocationPermissionStrategy new];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ - (void)checkServiceStatus:(PermissionGroup)permission completionHandler:(Servic
completionHandler(ServiceStatusNotApplicable);
}

- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler errorHandler:(PermissionErrorHandler)errorHandler{
PermissionStatus status = [self checkPermissionStatus:permission];
if (status != PermissionStatusDenied) {
completionHandler(status);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ - (void)checkServiceStatus:(PermissionGroup)permission completionHandler:(Servic
completionHandler(ServiceStatusNotApplicable);
}

- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler errorHandler:(PermissionErrorHandler)errorHandler {
PermissionStatus status = [self checkPermissionStatus:permission];
if (status != PermissionStatusDenied) {
completionHandler(status);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ - (void)checkServiceStatus:(PermissionGroup)permission completionHandler:(Servic
completionHandler(ServiceStatusNotApplicable);
}

- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler errorHandler:(PermissionErrorHandler)errorHandler {
PermissionStatus status = [self checkPermissionStatus:permission];

if (status != PermissionStatusDenied) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ - (void)checkServiceStatus:(PermissionGroup)permission completionHandler:(Servic
completionHandler(ServiceStatusNotApplicable);
}

- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler errorHandler:(PermissionErrorHandler)errorHandler {
completionHandler([BackgroundRefreshStrategy permissionStatus]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ - (void)handleCheckServiceStatusCallback:(CBCentralManager *)centralManager {
_serviceStatusHandler(serviceStatus);
}

- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler errorHandler:(PermissionErrorHandler)errorHandler {
[self initManagerIfNeeded];
PermissionStatus status = [self checkPermissionStatus:permission];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ - (void)checkServiceStatus:(PermissionGroup)permission completionHandler:(Servic
completionHandler(ServiceStatusNotApplicable);
}

- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler errorHandler:(PermissionErrorHandler)errorHandler {
PermissionStatus status = [self checkPermissionStatus:permission];

if (status != PermissionStatusDenied) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ - (void)checkServiceStatus:(PermissionGroup)permission completionHandler:(Servic
completionHandler(ServiceStatusNotApplicable);
}

- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler errorHandler:(PermissionErrorHandler)errorHandler {
PermissionStatus status = [self checkPermissionStatus:permission];
if (status != PermissionStatusDenied) {
completionHandler(status);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ - (void)checkServiceStatus:(PermissionGroup)permission completionHandler:(Servic
completionHandler(ServiceStatusNotApplicable);
}

- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler errorHandler:(PermissionErrorHandler)errorHandler {
PermissionStatus permissionStatus = [self checkPermissionStatus:permission];

if (permissionStatus != PermissionStatusDenied) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#import <Foundation/Foundation.h>
#import "PermissionStrategy.h"

#if PERMISSION_LOCATION
#if PERMISSION_LOCATION || PERMISSION_LOCATION_WHENINUSE || PERMISSION_LOCATION_ALWAYS

#import <CoreLocation/CoreLocation.h>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#import "LocationPermissionStrategy.h"

#if PERMISSION_LOCATION
#if PERMISSION_LOCATION || PERMISSION_LOCATION_WHENINUSE || PERMISSION_LOCATION_ALWAYS

NSString *const UserDefaultPermissionRequestedKey = @"org.baseflow.permission_handler_apple.permission_requested";

Expand Down Expand Up @@ -39,7 +39,7 @@ - (void)checkServiceStatus:(PermissionGroup)permission completionHandler:(Servic
completionHandler([CLLocationManager locationServicesEnabled] ? ServiceStatusEnabled : ServiceStatusDisabled);
}

- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler errorHandler:(PermissionErrorHandler)errorHandler {
PermissionStatus status = [self checkPermissionStatus:permission];
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse && permission == PermissionGroupLocationAlways) {
BOOL alreadyRequested = [[NSUserDefaults standardUserDefaults] boolForKey:UserDefaultPermissionRequestedKey]; // check if already requested the permantent permission
Expand All @@ -56,26 +56,47 @@ - (void)requestPermission:(PermissionGroup)permission completionHandler:(Permiss
_requestedPermission = permission;

if (permission == PermissionGroupLocation) {
if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"] != nil) {
#if PERMISSION_LOCATION
bool hasAlwaysInInfoPlist = ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"] != nil || [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysAndWhenInUseUsageDescription"] != nil);

if (hasAlwaysInInfoPlist && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse) {
[_locationManager requestAlwaysAuthorization];
} else if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"] != nil) {
[_locationManager requestWhenInUseAuthorization];
} else {
[[NSException exceptionWithName:NSInternalInconsistencyException reason:@"To use location in iOS8 you need to define either NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription in the app bundle's Info.plist file" userInfo:nil] raise];
errorHandler(@"MISSING_USAGE_DESCRIPTION", @"To use location from iOS8 you need to define at least NSLocationWhenInUseUsageDescription and optionally NSLocationAlwaysAndWhenInUseUsageDescription in the app bundle's Info.plist file");
return;
}
#else
if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"] != nil ) {
[_locationManager requestWhenInUseAuthorization];
} else {
errorHandler(@"MISSING_USAGE_DESCRIPTION", @"To use location from iOS8 you need to define at least NSLocationWhenInUseUsageDescription and optionally NSLocationAlwaysAndWhenInUseUsageDescription in the app bundle's Info.plist file");
return;
}
#endif
} else if (permission == PermissionGroupLocationAlways) {
if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"] != nil) {
#if PERMISSION_LOCATION
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
errorHandler(@"MISSING_WHENINUSE_PERMISSION", @"Must have \"When in use\" permission before it is allowed to request \"Always\" permission.");
return;
}

if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"] != nil || [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysAndWhenInUseUsageDescription"] != nil ) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveActivityNotification:) name:UIApplicationDidBecomeActiveNotification object:nil];
[_locationManager requestAlwaysAuthorization];
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:UserDefaultPermissionRequestedKey];
} else {
[[NSException exceptionWithName:NSInternalInconsistencyException reason:@"To use location in iOS8 you need to define NSLocationAlwaysUsageDescription in the app bundle's Info.plist file" userInfo:nil] raise];
errorHandler(@"MISSING_USAGE_DESCRIPTION", @"To always use location from iOS8 you need to define at least NSLocationWhenInUseUsageDescription and optionally NSLocationAlwaysAndWhenInUseUsageDescription in the app bundle's Info.plist file");
return;
}
#endif
} else if (permission == PermissionGroupLocationWhenInUse) {
if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"] != nil) {
if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"] != nil ) {
[_locationManager requestWhenInUseAuthorization];
} else {
[[NSException exceptionWithName:NSInternalInconsistencyException reason:@"To use location in iOS8 you need to define NSLocationWhenInUseUsageDescription in the app bundle's Info.plist file" userInfo:nil] raise];
errorHandler(@"MISSING_USAGE_DESCRIPTION", @"To use location from iOS8 you need to define at least NSLocationWhenInUseUsageDescription and optionally NSLocationAlwaysAndWhenInUseUsageDescription in the app bundle's Info.plist file");
return;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ - (void)checkServiceStatus:(PermissionGroup)permission completionHandler:(Servic
completionHandler(ServiceStatusNotApplicable);
}

- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler errorHandler:(PermissionErrorHandler)errorHandler {
PermissionStatus status = [self checkPermissionStatus:permission];
if (status != PermissionStatusDenied) {
completionHandler(status);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ - (void)checkServiceStatus:(PermissionGroup)permission completionHandler:(Servic
completionHandler(ServiceStatusNotApplicable);
}

- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler errorHandler:(PermissionErrorHandler)errorHandler {
PermissionStatus status = [self checkPermissionStatus:permission];
if (@available(iOS 12.0, *)) {
if (status != PermissionStatusDenied && status != PermissionStatusProvisional) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@

typedef void (^ServiceStatusHandler)(ServiceStatus serviceStatus);
typedef void (^PermissionStatusHandler)(PermissionStatus permissionStatus);
typedef void (^PermissionErrorHandler)(NSString* errorCode, NSString* errorDescription);

@protocol PermissionStrategy <NSObject>
- (PermissionStatus)checkPermissionStatus:(PermissionGroup)permission;

- (void)checkServiceStatus:(PermissionGroup)permission completionHandler:(ServiceStatusHandler)completionHandler;

- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler;
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler errorHandler:(PermissionErrorHandler)errorHandler;
@end
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ - (void)checkServiceStatus:(PermissionGroup)permission completionHandler:(Servic
completionHandler([self canDevicePlaceAPhoneCall] ? ServiceStatusEnabled : ServiceStatusDisabled);
}

- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler errorHandler:(PermissionErrorHandler)errorHandler {
completionHandler(PermissionStatusPermanentlyDenied);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ - (void)checkServiceStatus:(PermissionGroup)permission completionHandler:(Servic
completionHandler(ServiceStatusNotApplicable);
}

- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler {
- (void)requestPermission:(PermissionGroup)permission completionHandler:(PermissionStatusHandler)completionHandler errorHandler:(PermissionErrorHandler)errorHandler {
PermissionStatus status = [self checkPermissionStatus:permission];

if (status != PermissionStatusDenied) {
Expand Down
Loading

0 comments on commit 234c5f9

Please sign in to comment.