ReactNativePermissions.m 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. //
  2. // ReactNativePermissions.m
  3. // ReactNativePermissions
  4. //
  5. // Created by Yonah Forst on 18/02/16.
  6. // Copyright © 2016 Yonah Forst. All rights reserved.
  7. //
  8. #import "ReactNativePermissions.h"
  9. #import "RCTBridge.h"
  10. #import "RCTConvert.h"
  11. #import "RCTEventDispatcher.h"
  12. #import "RCTConvert+RNPermissionsStatus.h"
  13. #import <AddressBook/AddressBook.h>
  14. #import <AssetsLibrary/AssetsLibrary.h>
  15. #import <EventKit/EventKit.h>
  16. #import <CoreLocation/CoreLocation.h>
  17. #import <AVFoundation/AVFoundation.h>
  18. #import <CoreBluetooth/CoreBluetooth.h>
  19. @interface ReactNativePermissions()
  20. @end
  21. @implementation ReactNativePermissions
  22. RCT_EXPORT_MODULE();
  23. @synthesize bridge = _bridge;
  24. #pragma mark Initialization
  25. - (instancetype)init
  26. {
  27. if (self = [super init]) {
  28. }
  29. return self;
  30. }
  31. - (NSDictionary *)constantsToExport
  32. {
  33. return @{ @"StatusUndetermined" : @(RNPermissionsStatusUndetermined),
  34. @"StatusDenied" : @(RNPermissionsStatusDenied),
  35. @"StatusAuthorized" : @(RNPermissionsStatusAuthorized),
  36. @"StatusRestricted" : @(RNPermissionsStatusRestricted)};
  37. };
  38. RCT_EXPORT_METHOD(openSettings)
  39. {
  40. BOOL canOpenSettings = (&UIApplicationOpenSettingsURLString != NULL);
  41. if (canOpenSettings) {
  42. NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
  43. [[UIApplication sharedApplication] openURL:url];
  44. }
  45. }
  46. RCT_REMAP_METHOD(locationPermissionStatus, locationPermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
  47. {
  48. int status = [CLLocationManager authorizationStatus];
  49. switch (status) {
  50. case kCLAuthorizationStatusAuthorizedAlways:
  51. case kCLAuthorizationStatusAuthorizedWhenInUse:
  52. return resolve(@(RNPermissionsStatusAuthorized));
  53. case kCLAuthorizationStatusDenied:
  54. return resolve(@(RNPermissionsStatusDenied));
  55. case kCLAuthorizationStatusRestricted:
  56. return resolve(@(RNPermissionsStatusRestricted));
  57. default:
  58. return resolve(@(RNPermissionsStatusUndetermined));
  59. }
  60. }
  61. RCT_REMAP_METHOD(cameraPermissionStatus, cameraPermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
  62. {
  63. int status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
  64. switch (status) {
  65. case AVAuthorizationStatusAuthorized:
  66. return resolve(@(RNPermissionsStatusAuthorized));
  67. case AVAuthorizationStatusDenied:
  68. return resolve(@(RNPermissionsStatusDenied));
  69. case AVAuthorizationStatusRestricted:
  70. return resolve(@(RNPermissionsStatusRestricted));
  71. default:
  72. return resolve(@(RNPermissionsStatusUndetermined));
  73. }
  74. }
  75. RCT_REMAP_METHOD(microphonePermissionStatus, microphonePermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
  76. {
  77. int status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
  78. switch (status) {
  79. case AVAuthorizationStatusAuthorized:
  80. return resolve(@(RNPermissionsStatusAuthorized));
  81. case AVAuthorizationStatusDenied:
  82. return resolve(@(RNPermissionsStatusDenied));
  83. case AVAuthorizationStatusRestricted:
  84. return resolve(@(RNPermissionsStatusRestricted));
  85. default:
  86. return resolve(@(RNPermissionsStatusUndetermined));
  87. }
  88. }
  89. RCT_REMAP_METHOD(photoPermissionStatus, photoPermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
  90. {
  91. int status = [ALAssetsLibrary authorizationStatus];
  92. switch (status) {
  93. case ALAuthorizationStatusAuthorized:
  94. return resolve(@(RNPermissionsStatusAuthorized));
  95. case ALAuthorizationStatusDenied:
  96. return resolve(@(RNPermissionsStatusDenied));
  97. case ALAuthorizationStatusRestricted:
  98. return resolve(@(RNPermissionsStatusRestricted));
  99. default:
  100. return resolve(@(RNPermissionsStatusUndetermined));
  101. }
  102. }
  103. RCT_REMAP_METHOD(contactsPermissionStatus, contactsPermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
  104. {
  105. int status = ABAddressBookGetAuthorizationStatus();
  106. switch (status) {
  107. case kABAuthorizationStatusAuthorized:
  108. return resolve(@(RNPermissionsStatusAuthorized));
  109. case kABAuthorizationStatusDenied:
  110. return resolve(@(RNPermissionsStatusDenied));
  111. case kABAuthorizationStatusRestricted:
  112. return resolve(@(RNPermissionsStatusRestricted));
  113. default:
  114. return resolve(@(RNPermissionsStatusUndetermined));
  115. }
  116. }
  117. RCT_REMAP_METHOD(eventPermissionStatus, eventPermission:(NSString *)eventString resolve:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
  118. {
  119. int status;
  120. if ([eventString isEqualToString:@"reminder"]) {
  121. status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeReminder];
  122. } else if ([eventString isEqualToString:@"event"]) {
  123. status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];
  124. } else {
  125. NSError *error = [NSError errorWithDomain:@"invalidOption" code:-1 userInfo:NULL];
  126. return reject(@"-1", @"Type must be 'reminder' or 'event'", error);
  127. }
  128. switch (status) {
  129. case EKAuthorizationStatusAuthorized:
  130. return resolve(@(RNPermissionsStatusAuthorized));
  131. case EKAuthorizationStatusDenied:
  132. return resolve(@(RNPermissionsStatusDenied));
  133. case EKAuthorizationStatusRestricted:
  134. return resolve(@(RNPermissionsStatusRestricted));
  135. default:
  136. return resolve(@(RNPermissionsStatusUndetermined));
  137. }
  138. }
  139. RCT_REMAP_METHOD(bluetoothPermissionStatus, bluetoothPermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
  140. {
  141. int status = [CBPeripheralManager authorizationStatus];
  142. switch (status) {
  143. case CBPeripheralManagerAuthorizationStatusAuthorized:
  144. return resolve(@(RNPermissionsStatusAuthorized));
  145. case CBPeripheralManagerAuthorizationStatusDenied:
  146. return resolve(@(RNPermissionsStatusDenied));
  147. case CBPeripheralManagerAuthorizationStatusRestricted:
  148. return resolve(@(RNPermissionsStatusRestricted));
  149. default:
  150. return resolve(@(RNPermissionsStatusUndetermined));
  151. }
  152. }
  153. //problem here is that we can only return Authorized or Undetermined
  154. RCT_REMAP_METHOD(notificationPermissionStatus, notificationPermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
  155. {
  156. if ([[UIApplication sharedApplication] respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) {
  157. // iOS8+
  158. if ([[UIApplication sharedApplication] isRegisteredForRemoteNotifications]) {
  159. return resolve(@(RNPermissionsStatusAuthorized));
  160. }
  161. else {
  162. return resolve(@(RNPermissionsStatusUndetermined));
  163. }
  164. } else {
  165. if ([[UIApplication sharedApplication] enabledRemoteNotificationTypes] == UIRemoteNotificationTypeNone) {
  166. return resolve(@(RNPermissionsStatusUndetermined));
  167. }
  168. else {
  169. return resolve(@(RNPermissionsStatusAuthorized));
  170. }
  171. }
  172. }
  173. @end