123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #import "RNPermissionHandlerNotifications.h"
  2. @import UserNotifications;
  3. @import UIKit;
  4. @interface RNPermissionHandlerNotifications()
  5. @property (nonatomic, strong) void (^resolve)(RNPermissionStatus status, NSDictionary * _Nonnull settings);
  6. @property (nonatomic, strong) void (^reject)(NSError *error);
  7. @end
  8. @implementation RNPermissionHandlerNotifications
  9. + (NSString * _Nonnull)handlerUniqueId {
  10. return @"ios.permission.NOTIFICATIONS";
  11. }
  12. - (void)checkWithResolver:(void (^ _Nonnull)(RNPermissionStatus status, NSDictionary * _Nonnull settings))resolve
  13. rejecter:(void (^ _Nonnull)(NSError * _Nonnull error))reject {
  14. if (@available(iOS 10.0, *)) {
  15. [[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
  16. NSMutableDictionary *result = [NSMutableDictionary new];
  17. bool alert = settings.alertSetting == UNNotificationSettingEnabled;
  18. bool badge = settings.badgeSetting == UNNotificationSettingEnabled;
  19. bool sound = settings.soundSetting == UNNotificationSettingEnabled;
  20. bool lockScreen = settings.lockScreenSetting == UNNotificationSettingEnabled;
  21. bool carPlay = settings.carPlaySetting == UNNotificationSettingEnabled;
  22. bool notificationCenter = settings.notificationCenterSetting == UNNotificationSettingEnabled;
  23. if (settings.alertSetting != UNNotificationSettingNotSupported)
  24. [result setValue:@(alert) forKey:@"alert"];
  25. if (settings.badgeSetting != UNNotificationSettingNotSupported)
  26. [result setValue:@(badge) forKey:@"badge"];
  27. if (settings.soundSetting != UNNotificationSettingNotSupported)
  28. [result setValue:@(sound) forKey:@"sound"];
  29. if (settings.lockScreenSetting != UNNotificationSettingNotSupported)
  30. [result setValue:@(lockScreen) forKey:@"lockScreen"];
  31. if (settings.carPlaySetting != UNNotificationSettingNotSupported)
  32. [result setValue:@(carPlay) forKey:@"carPlay"];
  33. if (settings.notificationCenterSetting != UNNotificationSettingNotSupported)
  34. [result setValue:@(notificationCenter) forKey:@"notificationCenter"];
  35. if (@available(iOS 12.0, *)) {
  36. bool criticalAlert = settings.criticalAlertSetting == UNNotificationSettingEnabled;
  37. if (settings.criticalAlertSetting != UNNotificationSettingNotSupported)
  38. [result setValue:@(criticalAlert) forKey:@"criticalAlert"];
  39. }
  40. switch (settings.authorizationStatus) {
  41. case UNAuthorizationStatusNotDetermined:
  42. #ifdef __IPHONE_12_0
  43. case UNAuthorizationStatusProvisional:
  44. #endif
  45. return resolve(RNPermissionStatusNotDetermined, result);
  46. case UNAuthorizationStatusDenied:
  47. return resolve(RNPermissionStatusDenied, result);
  48. case UNAuthorizationStatusAuthorized:
  49. return resolve(RNPermissionStatusAuthorized, result);
  50. }
  51. }];
  52. } else {
  53. UIUserNotificationSettings *settings = [[UIApplication sharedApplication] currentUserNotificationSettings];
  54. UIUserNotificationType types = [settings types];
  55. NSDictionary *result = @{
  56. @"alert": @((bool)(types & UIUserNotificationTypeAlert)),
  57. @"badge": @((bool)(types & UIUserNotificationTypeBadge)),
  58. @"sound": @((bool)(types & UIUserNotificationTypeSound)),
  59. };
  60. if (types != UIUserNotificationTypeNone) {
  61. return resolve(RNPermissionStatusAuthorized, result);
  62. } else if ([RNPermissions isFlaggedAsRequested:[[self class] handlerUniqueId]]) {
  63. return resolve(RNPermissionStatusDenied, result);
  64. } else {
  65. return resolve(RNPermissionStatusNotDetermined, result);
  66. }
  67. }
  68. }
  69. - (void)requestWithResolver:(void (^ _Nonnull)(RNPermissionStatus status, NSDictionary * _Nonnull settings))resolve
  70. rejecter:(void (^ _Nonnull)(NSError * _Nonnull error))reject
  71. options:(NSArray<NSString *> * _Nonnull)options {
  72. _resolve = resolve;
  73. _reject = reject;
  74. bool alert = [options containsObject:@"alert"];
  75. bool badge = [options containsObject:@"badge"];
  76. bool sound = [options containsObject:@"sound"];
  77. bool criticalAlert = [options containsObject:@"criticalAlert"];
  78. bool carPlay = [options containsObject:@"carPlay"];
  79. bool provisional = [options containsObject:@"provisional"];
  80. if (@available(iOS 10.0, *)) {
  81. UNAuthorizationOptions types = UNAuthorizationOptionNone;
  82. if (alert) types += UNAuthorizationOptionAlert;
  83. if (badge) types += UNAuthorizationOptionBadge;
  84. if (sound) types += UNAuthorizationOptionSound;
  85. if (carPlay) types += UNAuthorizationOptionCarPlay;
  86. if (@available(iOS 12.0, *)) {
  87. if (criticalAlert) types += UNAuthorizationOptionCriticalAlert;
  88. if (provisional) types += UNAuthorizationOptionProvisional;
  89. }
  90. if (!alert &&
  91. !badge &&
  92. !sound &&
  93. !criticalAlert &&
  94. !carPlay &&
  95. !provisional) {
  96. types += UNAuthorizationOptionAlert;
  97. types += UNAuthorizationOptionBadge;
  98. types += UNAuthorizationOptionSound;
  99. }
  100. [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:types
  101. completionHandler:^(BOOL granted, NSError * _Nullable error) {
  102. if (error != nil) {
  103. return reject(error);
  104. }
  105. if (granted) {
  106. dispatch_async(dispatch_get_main_queue(), ^{
  107. [[UIApplication sharedApplication] registerForRemoteNotifications];
  108. });
  109. }
  110. [RNPermissions flagAsRequested:[[self class] handlerUniqueId]];
  111. [self checkWithResolver:self->_resolve rejecter:self->_reject];
  112. }];
  113. } else {
  114. if ([RNPermissions isFlaggedAsRequested:[[self class] handlerUniqueId]]) {
  115. [self checkWithResolver:_resolve rejecter:_reject];
  116. } else {
  117. UIUserNotificationType types = UIUserNotificationTypeNone;
  118. if (alert) types += UIUserNotificationTypeAlert;
  119. if (badge) types += UIUserNotificationTypeBadge;
  120. if (sound) types += UIUserNotificationTypeSound;
  121. if (!alert &&
  122. !badge &&
  123. !sound) {
  124. types += UIUserNotificationTypeAlert;
  125. types += UIUserNotificationTypeBadge;
  126. types += UIUserNotificationTypeSound;
  127. }
  128. [[NSNotificationCenter defaultCenter] addObserver:self
  129. selector:@selector(onApplicationDidBecomeActive)
  130. name:UIApplicationDidBecomeActiveNotification
  131. object:nil];
  132. UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
  133. [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
  134. [[UIApplication sharedApplication] registerForRemoteNotifications];
  135. }
  136. }
  137. }
  138. - (void)onApplicationDidBecomeActive {
  139. [[NSNotificationCenter defaultCenter] removeObserver:self
  140. name:UIApplicationDidBecomeActiveNotification
  141. object:nil];
  142. [RNPermissions flagAsRequested:[[self class] handlerUniqueId]];
  143. [self checkWithResolver:_resolve rejecter:_reject];
  144. }
  145. @end