diff --git a/README.md b/README.md index 1ac090d68..0058b462a 100644 --- a/README.md +++ b/README.md @@ -316,6 +316,8 @@ request is an object containing: - `sound` : The sound played when the notification is fired. - `category` : The category of this notification, required for actionable notifications. - `isSilent` : If true, the notification will appear without sound. +- `isCritical` : If true, the notification sound be played even when the device is locked, muted, or has Do Not Disturb enabled. +- `criticalSoundVolume` : A number between 0 and 1 for volume of critical notification. Default volume will be used if not specified. - `userInfo` : An object containing additional notification data. --- @@ -548,6 +550,9 @@ Requests notification permissions from iOS, prompting the user's dialog box. By - `alert` - `badge` - `sound` +- `critical` + +`critical` requires special entitlement that could be requested here: https://developer.apple.com/contact/request/notifications-critical-alerts-entitlement/ If a map is provided to the method, only the permissions with truthy values will be requested. @@ -555,9 +560,9 @@ This method returns a promise that will resolve when the user accepts, rejects, **Parameters:** -| Name | Type | Required | Description | -| ----------- | ----- | -------- | ---------------------- | -| permissions | array | No | alert, badge, or sound | +| Name | Type | Required | Description | +| ----------- | ----- | -------- | ------------------------------- | +| permissions | array | No | alert, badge, sound or critical | --- @@ -592,6 +597,7 @@ See what push permissions are currently enabled. - `alert` :boolean - `badge` :boolean - `sound` :boolean +- `critical` :boolean - `lockScreen` :boolean - `notificationCenter` :boolean - `authorizationStatus` :AuthorizationStatus diff --git a/index.d.ts b/index.d.ts index d59ba22a4..13679d261 100644 --- a/index.d.ts +++ b/index.d.ts @@ -178,6 +178,14 @@ export type NotificationRequest = { * Sets notification to be silent */ isSilent?: boolean; + /** + * Sets notification to be critical + */ + isCritical?: boolean; + /** + * The volume for the critical alert’s sound. Set this to a value between 0.0 (silent) and 1.0 (full volume). + */ + criticalSoundVolume?: number; /** * Optional data to be added to the notification */ @@ -291,6 +299,7 @@ export interface PushNotificationPermissions { alert?: boolean; badge?: boolean; sound?: boolean; + critical?: boolean; lockScreen?: boolean; notificationCenter?: boolean; authorizationStatus?: AuthorizationStatus[keyof AuthorizationStatus]; diff --git a/ios/RCTConvert+Notification.m b/ios/RCTConvert+Notification.m index 434ef80a4..9efb776a6 100644 --- a/ios/RCTConvert+Notification.m +++ b/ios/RCTConvert+Notification.m @@ -95,6 +95,8 @@ + (UNNotificationRequest *)UNNotificationRequest:(id)json NSDictionary *details = [self NSDictionary:json]; BOOL isSilent = [RCTConvert BOOL:details[@"isSilent"]]; + BOOL isCritical = [RCTConvert BOOL:details[@"isCritical"]]; + float criticalSoundVolume = [RCTConvert float:details[@"criticalSoundVolume"]]; NSString* identifier = [RCTConvert NSString:details[@"id"]]; @@ -112,7 +114,15 @@ + (UNNotificationRequest *)UNNotificationRequest:(id)json content.userInfo = [RCTConvert NSDictionary:details[@"userInfo"]]; if (!isSilent) { - content.sound = [RCTConvert NSString:details[@"sound"]] ? [UNNotificationSound soundNamed:[RCTConvert NSString:details[@"sound"]]] : [UNNotificationSound defaultSound]; + if (isCritical) { + if (criticalSoundVolume) { + content.sound = [RCTConvert NSString:details[@"sound"]] ? [UNNotificationSound criticalSoundNamed:[RCTConvert NSString:details[@"sound"]] withAudioVolume:criticalSoundVolume] : [UNNotificationSound defaultCriticalSoundWithAudioVolume:criticalSoundVolume]; + } else { + content.sound = [RCTConvert NSString:details[@"sound"]] ? [UNNotificationSound criticalSoundNamed:[RCTConvert NSString:details[@"sound"]]] : [UNNotificationSound defaultCriticalSound]; + } + } else { + content.sound = [RCTConvert NSString:details[@"sound"]] ? [UNNotificationSound soundNamed:[RCTConvert NSString:details[@"sound"]]] : [UNNotificationSound defaultSound]; + } } NSDate* fireDate = [RCTConvert NSDate:details[@"fireDate"]]; diff --git a/ios/RNCPushNotificationIOS.m b/ios/RNCPushNotificationIOS.m index 89adf61d9..3ef7bf4f0 100644 --- a/ios/RNCPushNotificationIOS.m +++ b/ios/RNCPushNotificationIOS.m @@ -212,6 +212,9 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification if ([RCTConvert BOOL:permissions[@"sound"]]) { types |= UNAuthorizationOptionSound; } + if ([RCTConvert BOOL:permissions[@"critical"]]) { + types |= UNAuthorizationOptionCriticalAlert; + } } else { types = UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound; } @@ -241,7 +244,7 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification RCT_EXPORT_METHOD(checkPermissions:(RCTResponseSenderBlock)callback) { if (RCTRunningInAppExtension()) { - callback(@[RCTSettingsDictForUNNotificationSettings(NO, NO, NO, NO, NO, UNAuthorizationStatusNotDetermined)]); + callback(@[RCTSettingsDictForUNNotificationSettings(NO, NO, NO, NO, NO, NO, UNAuthorizationStatusNotDetermined)]); return; } @@ -254,13 +257,14 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification return RCTSettingsDictForUNNotificationSettings(settings.alertSetting == UNNotificationSettingEnabled, settings.badgeSetting == UNNotificationSettingEnabled, settings.soundSetting == UNNotificationSettingEnabled, + settings.criticalAlertSetting == UNNotificationSettingEnabled, settings.lockScreenSetting == UNNotificationSettingEnabled, settings.notificationCenterSetting == UNNotificationSettingEnabled, settings.authorizationStatus); } -static inline NSDictionary *RCTSettingsDictForUNNotificationSettings(BOOL alert, BOOL badge, BOOL sound, BOOL lockScreen, BOOL notificationCenter, UNAuthorizationStatus authorizationStatus) { - return @{@"alert": @(alert), @"badge": @(badge), @"sound": @(sound), @"lockScreen": @(lockScreen), @"notificationCenter": @(notificationCenter), @"authorizationStatus": @(authorizationStatus)}; +static inline NSDictionary *RCTSettingsDictForUNNotificationSettings(BOOL alert, BOOL badge, BOOL sound, BOOL critical, BOOL lockScreen, BOOL notificationCenter, UNAuthorizationStatus authorizationStatus) { + return @{@"alert": @(alert), @"badge": @(badge), @"sound": @(sound), @"critical": @(critical), @"lockScreen": @(lockScreen), @"notificationCenter": @(notificationCenter), @"authorizationStatus": @(authorizationStatus)}; } /** diff --git a/js/index.js b/js/index.js index ad76ed8bb..1d3ae7d06 100644 --- a/js/index.js +++ b/js/index.js @@ -379,10 +379,12 @@ class PushNotificationIOS { alert?: boolean, badge?: boolean, sound?: boolean, + critical?: boolean, }): Promise<{ alert: boolean, badge: boolean, sound: boolean, + critical: boolean, }> { let requestedPermissions = { alert: true, @@ -394,6 +396,7 @@ class PushNotificationIOS { alert: !!permissions.alert, badge: !!permissions.badge, sound: !!permissions.sound, + critical: !!permissions.critical, }; } invariant(