RNPermissionHandlerNotifications.m 6.8KB

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