1// Copyright 2019-present 650 Industries. All rights reserved. 2 3#import "EXPermissionsManager.h" 4#import "EXEnvironment.h" 5 6NSString * const EXPermissionsKey = @"ExpoPermissions"; 7 8@interface EXPermissionsManager () 9 10@property (nonatomic, strong) NSMutableDictionary<NSString *, NSDictionary *> *permissionsCache; 11 12@end 13 14@implementation EXPermissionsManager 15 16- (instancetype)init 17{ 18 if (self = [super init]) { 19 NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 20 NSDictionary *expoPermissions = [userDefaults dictionaryForKey:EXPermissionsKey]; 21 _permissionsCache = expoPermissions ? [[NSMutableDictionary alloc] initWithDictionary:expoPermissions] : [NSMutableDictionary new]; 22 } 23 return self; 24} 25 26UM_REGISTER_SINGLETON_MODULE(Permissions) 27 28- (UMPermissionStatus)getPermission:(NSString *)permissionType forExperience:(NSString *)experienceId 29{ 30 permissionType = [EXPermissionsManager mapPermissionType:permissionType]; 31 32 NSString *experienceIdKey = [EXPermissionsManager escapedResourceName:experienceId]; 33 NSDictionary *experiencePermissions = _permissionsCache[experienceIdKey]; 34 if (!experiencePermissions) { 35 return UMPermissionStatusUndetermined; 36 } 37 38 NSDictionary *permissionData = experiencePermissions[permissionType]; 39 if (!permissionData) { 40 return UMPermissionStatusUndetermined; 41 } 42 43 if ([permissionData[@"status"] isEqualToString:[EXPermissionsService permissionStringForStatus:UMPermissionStatusGranted]]) { 44 return UMPermissionStatusGranted; 45 } 46 47 return UMPermissionStatusDenied; 48} 49 50- (BOOL)hasGrantedPermission:(NSString *)permission forExperience:(NSString *)experienceId 51{ 52 if ([EXEnvironment sharedEnvironment].isDetached) { 53 return YES; 54 } 55 56 return [self getPermission:[EXPermissionsManager mapPermissionType:permission] forExperience:experienceId] == UMPermissionStatusGranted; 57} 58 59- (BOOL)savePermission:(NSDictionary *)permission ofType:(NSString *)type forExperience:(NSString *)experienceId 60{ 61 type = [EXPermissionsManager mapPermissionType:type]; 62 63 NSString *experienceIdKey = [EXPermissionsManager escapedResourceName:experienceId]; 64 NSMutableDictionary *experiencePermissions; 65 if ([_permissionsCache objectForKey:experienceIdKey] == nil) { 66 experiencePermissions = [[NSMutableDictionary alloc] init]; 67 } else { 68 experiencePermissions = [[NSMutableDictionary alloc] initWithDictionary:_permissionsCache[experienceIdKey]]; 69 } 70 71 experiencePermissions[type] = permission; 72 _permissionsCache[experienceIdKey] = experiencePermissions; 73 [self synchronizeWithPermissions:_permissionsCache]; 74 return YES; 75} 76 77- (void)synchronizeWithPermissions:(NSDictionary *)permissions 78{ 79 [[NSUserDefaults standardUserDefaults] setObject:permissions forKey:EXPermissionsKey]; 80} 81 82+ (NSString *)escapedResourceName:(NSString *)name 83{ 84 NSString *charactersToEscape = @"!*'();:@&=+$,/?%#[]"; 85 NSCharacterSet *allowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:charactersToEscape] invertedSet]; 86 return [name stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters]; 87} 88 89+ (NSString *)mapPermissionType:(NSString *)type 90{ 91 if ([type isEqual:@"locationForeground"]) { 92 return @"location"; 93 } 94 95 return type; 96} 97 98@end 99