ReactNativePermissions.m 8.2KB

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