#import "RNPermissions.h" #import #if __has_include("RNPermissionHandlerBluetoothPeripheral.h") #import "RNPermissionHandlerBluetoothPeripheral.h" #endif #if __has_include("RNPermissionHandlerCalendars.h") #import "RNPermissionHandlerCalendars.h" #endif #if __has_include("RNPermissionHandlerCamera.h") #import "RNPermissionHandlerCamera.h" #endif #if __has_include("RNPermissionHandlerContacts.h") #import "RNPermissionHandlerContacts.h" #endif #if __has_include("RNPermissionHandlerFaceID.h") #import "RNPermissionHandlerFaceID.h" #endif #if __has_include("RNPermissionHandlerLocationAlways.h") #import "RNPermissionHandlerLocationAlways.h" #endif #if __has_include("RNPermissionHandlerLocationWhenInUse.h") #import "RNPermissionHandlerLocationWhenInUse.h" #endif #if __has_include("RNPermissionHandlerMediaLibrary.h") #import "RNPermissionHandlerMediaLibrary.h" #endif #if __has_include("RNPermissionHandlerMicrophone.h") #import "RNPermissionHandlerMicrophone.h" #endif #if __has_include("RNPermissionHandlerMotion.h") #import "RNPermissionHandlerMotion.h" #endif #if __has_include("RNPermissionHandlerNotifications.h") #import "RNPermissionHandlerNotifications.h" #endif #if __has_include("RNPermissionHandlerPhotoLibrary.h") #import "RNPermissionHandlerPhotoLibrary.h" #endif #if __has_include("RNPermissionHandlerReminders.h") #import "RNPermissionHandlerReminders.h" #endif #if __has_include("RNPermissionHandlerSiri.h") #import "RNPermissionHandlerSiri.h" #endif #if __has_include("RNPermissionHandlerSpeechRecognition.h") #import "RNPermissionHandlerSpeechRecognition.h" #endif #if __has_include("RNPermissionHandlerStoreKit.h") #import "RNPermissionHandlerStoreKit.h" #endif static NSString* SETTING_KEY = @"@RNPermissions:Requested"; @implementation RCTConvert(RNPermission) RCT_ENUM_CONVERTER(RNPermission, (@{ #if __has_include("RNPermissionHandlerBluetoothPeripheral.h") [RNPermissionHandlerBluetoothPeripheral handlerUniqueId]: @(RNPermissionBluetoothPeripheral), #endif #if __has_include("RNPermissionHandlerCalendars.h") [RNPermissionHandlerCalendars handlerUniqueId]: @(RNPermissionCalendars), #endif #if __has_include("RNPermissionHandlerCamera.h") [RNPermissionHandlerCamera handlerUniqueId]: @(RNPermissionCamera), #endif #if __has_include("RNPermissionHandlerContacts.h") [RNPermissionHandlerContacts handlerUniqueId]: @(RNPermissionContacts), #endif #if __has_include("RNPermissionHandlerFaceID.h") [RNPermissionHandlerFaceID handlerUniqueId]: @(RNPermissionFaceID), #endif #if __has_include("RNPermissionHandlerLocationAlways.h") [RNPermissionHandlerLocationAlways handlerUniqueId]: @(RNPermissionLocationAlways), #endif #if __has_include("RNPermissionHandlerLocationWhenInUse.h") [RNPermissionHandlerLocationWhenInUse handlerUniqueId]: @(RNPermissionLocationWhenInUse), #endif #if __has_include("RNPermissionHandlerMediaLibrary.h") [RNPermissionHandlerMediaLibrary handlerUniqueId]: @(RNPermissionMediaLibrary), #endif #if __has_include("RNPermissionHandlerMicrophone.h") [RNPermissionHandlerMicrophone handlerUniqueId]: @(RNPermissionMicrophone), #endif #if __has_include("RNPermissionHandlerMotion.h") [RNPermissionHandlerMotion handlerUniqueId]: @(RNPermissionMotion), #endif #if __has_include("RNPermissionHandlerPhotoLibrary.h") [RNPermissionHandlerPhotoLibrary handlerUniqueId]: @(RNPermissionPhotoLibrary), #endif #if __has_include("RNPermissionHandlerReminders.h") [RNPermissionHandlerReminders handlerUniqueId]: @(RNPermissionReminders), #endif #if __has_include("RNPermissionHandlerSiri.h") [RNPermissionHandlerSiri handlerUniqueId]: @(RNPermissionSiri), #endif #if __has_include("RNPermissionHandlerSpeechRecognition.h") [RNPermissionHandlerSpeechRecognition handlerUniqueId]: @(RNPermissionSpeechRecognition), #endif #if __has_include("RNPermissionHandlerStoreKit.h") [RNPermissionHandlerStoreKit handlerUniqueId]: @(RNPermissionStoreKit), #endif }), RNPermissionUnknown, integerValue); @end @implementation RNPermissions RCT_EXPORT_MODULE(); + (BOOL)requiresMainQueueSetup { return YES; } - (dispatch_queue_t)methodQueue { return dispatch_get_main_queue(); } - (id _Nullable)handlerForPermission:(RNPermission)permission { id handler = nil; switch (permission) { #if __has_include("RNPermissionHandlerBluetoothPeripheral.h") case RNPermissionBluetoothPeripheral: handler = [RNPermissionHandlerBluetoothPeripheral new]; break; #endif #if __has_include("RNPermissionHandlerCalendars.h") case RNPermissionCalendars: handler = [RNPermissionHandlerCalendars new]; break; #endif #if __has_include("RNPermissionHandlerCamera.h") case RNPermissionCamera: handler = [RNPermissionHandlerCamera new]; break; #endif #if __has_include("RNPermissionHandlerContacts.h") case RNPermissionContacts: handler = [RNPermissionHandlerContacts new]; break; #endif #if __has_include("RNPermissionHandlerFaceID.h") case RNPermissionFaceID: handler = [RNPermissionHandlerFaceID new]; break; #endif #if __has_include("RNPermissionHandlerLocationAlways.h") case RNPermissionLocationAlways: handler = [RNPermissionHandlerLocationAlways new]; break; #endif #if __has_include("RNPermissionHandlerLocationWhenInUse.h") case RNPermissionLocationWhenInUse: handler = [RNPermissionHandlerLocationWhenInUse new]; break; #endif #if __has_include("RNPermissionHandlerMediaLibrary.h") case RNPermissionMediaLibrary: handler = [RNPermissionHandlerMediaLibrary new]; break; #endif #if __has_include("RNPermissionHandlerMicrophone.h") case RNPermissionMicrophone: handler = [RNPermissionHandlerMicrophone new]; break; #endif #if __has_include("RNPermissionHandlerMotion.h") case RNPermissionMotion: handler = [RNPermissionHandlerMotion new]; break; #endif #if __has_include("RNPermissionHandlerPhotoLibrary.h") case RNPermissionPhotoLibrary: handler = [RNPermissionHandlerPhotoLibrary new]; break; #endif #if __has_include("RNPermissionHandlerReminders.h") case RNPermissionReminders: handler = [RNPermissionHandlerReminders new]; break; #endif #if __has_include("RNPermissionHandlerSiri.h") case RNPermissionSiri: handler = [RNPermissionHandlerSiri new]; break; #endif #if __has_include("RNPermissionHandlerSpeechRecognition.h") case RNPermissionSpeechRecognition: handler = [RNPermissionHandlerSpeechRecognition new]; break; #endif #if __has_include("RNPermissionHandlerStoreKit.h") case RNPermissionStoreKit: handler = [RNPermissionHandlerStoreKit new]; break; #endif case RNPermissionUnknown: break; // RCTConvert prevents this case } #if RCT_DEV for (NSString *key in [[handler class] usageDescriptionKeys]) { if (![[NSBundle mainBundle] objectForInfoDictionaryKey:key]) { RCTLogError(@"Cannot check or request permission without the required \"%@\" entry in your app \"Info.plist\" file", key); return nil; } } #endif return handler; } - (NSString *)stringForStatus:(RNPermissionStatus)status { switch (status) { case RNPermissionStatusNotAvailable: case RNPermissionStatusRestricted: return @"unavailable"; case RNPermissionStatusNotDetermined: return @"denied"; case RNPermissionStatusDenied: return @"blocked"; case RNPermissionStatusAuthorized: return @"granted"; } } + (bool)isFlaggedAsRequested:(NSString * _Nonnull)handlerId { NSArray *requested = [[NSUserDefaults standardUserDefaults] arrayForKey:SETTING_KEY]; return requested == nil ? false : [requested containsObject:handlerId]; } + (void)flagAsRequested:(NSString * _Nonnull)handlerId { NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSMutableArray *requested = [[userDefaults arrayForKey:SETTING_KEY] mutableCopy]; if (requested == nil) { requested = [NSMutableArray new]; } if (![requested containsObject:handlerId]) { [requested addObject:handlerId]; [userDefaults setObject:requested forKey:SETTING_KEY]; [userDefaults synchronize]; } } + (bool)isBackgroundModeEnabled:(NSString * _Nonnull)mode { NSArray *modes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"]; return [modes isKindOfClass:[NSArray class]] && [modes containsObject:mode]; } RCT_REMAP_METHOD(openSettings, openSettingsWithResolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { UIApplication *sharedApplication = [UIApplication sharedApplication]; NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; if (@available(iOS 10.0, *)) { [sharedApplication openURL:url options:@{} completionHandler:^(BOOL success) { if (success) { resolve(@(true)); } else { reject(@"cannot_open_settings", @"Cannot open application settings", nil); } }]; } else { [sharedApplication openURL:url]; resolve(@(true)); } } RCT_REMAP_METHOD(check, checkWithPermission:(RNPermission)permission resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { id handler = [self handlerForPermission:permission]; [handler checkWithResolver:^(RNPermissionStatus status) { NSString *strStatus = [self stringForStatus:status]; NSLog(@"[react-native-permissions] %@ permission checked: %@", [[handler class] handlerUniqueId], strStatus); resolve(strStatus); } rejecter:^(NSError *error) { NSLog(@"[react-native-permissions] %@ permission failed: %@", [[handler class] handlerUniqueId], error.localizedDescription); reject([NSString stringWithFormat:@"%ld", (long)error.code], error.localizedDescription, error); }]; } RCT_REMAP_METHOD(request, requestWithPermission:(RNPermission)permission resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { id handler = [self handlerForPermission:permission]; [handler requestWithResolver:^(RNPermissionStatus status) { NSString *strStatus = [self stringForStatus:status]; NSLog(@"[react-native-permissions] %@ permission checked: %@", [[handler class] handlerUniqueId], strStatus); resolve(strStatus); } rejecter:^(NSError *error) { NSLog(@"[react-native-permissions] %@ permission failed: %@", [[handler class] handlerUniqueId], error.localizedDescription); reject([NSString stringWithFormat:@"%ld", (long)error.code], error.localizedDescription, error); }]; } RCT_REMAP_METHOD(checkNotifications, checkNotificationsWithResolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { #if __has_include("RNPermissionHandlerNotifications.h") RNPermissionHandlerNotifications *handler = [RNPermissionHandlerNotifications new]; [handler checkWithResolver:^(RNPermissionStatus status, NSDictionary * _Nonnull settings) { NSString *strStatus = [self stringForStatus:status]; NSLog(@"[react-native-permissions] %@ permission checked: %@", [[handler class] handlerUniqueId], strStatus); resolve(@{ @"status": strStatus, @"settings": settings }); } rejecter:^(NSError * _Nonnull error) { NSLog(@"[react-native-permissions] %@ permission failed: %@", [[handler class] handlerUniqueId], error.localizedDescription); reject([NSString stringWithFormat:@"%ld", (long)error.code], error.localizedDescription, error); }]; #else reject(@"notifications_pod_missing", @"Notifications permission pod is missing", nil); #endif } RCT_REMAP_METHOD(requestNotifications, requestNotificationsWithOptions:(NSArray * _Nonnull)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { #if __has_include("RNPermissionHandlerNotifications.h") RNPermissionHandlerNotifications *handler = [RNPermissionHandlerNotifications new]; [handler requestWithResolver:^(RNPermissionStatus status, NSDictionary * _Nonnull settings) { NSString *strStatus = [self stringForStatus:status]; NSLog(@"[react-native-permissions] %@ permission checked: %@", [[handler class] handlerUniqueId], strStatus); resolve(@{ @"status": strStatus, @"settings": settings }); } rejecter:^(NSError * _Nonnull error) { NSLog(@"[react-native-permissions] %@ permission failed: %@", [[handler class] handlerUniqueId], error.localizedDescription); reject([NSString stringWithFormat:@"%ld", (long)error.code], error.localizedDescription, error); } options:options]; #else reject(@"notifications_pod_missing", @"Notifications permission pod is missing", nil); #endif } @end