diff --git a/packages/react-native/Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js b/packages/react-native/Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js index 102ce795e77a04..6d83970816aec8 100644 --- a/packages/react-native/Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js +++ b/packages/react-native/Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js @@ -23,14 +23,20 @@ type Notification = {| // Actual type: string | number +fireDate?: ?number, +alertBody?: ?string, - +alertAction?: ?string, +userInfo?: ?Object, +category?: ?string, // Actual type: 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' +repeatInterval?: ?string, +applicationIconBadgeNumber?: ?number, +isSilent?: ?boolean, + /** + * Custom notification sound to play. Write-only: soundName will be null when + * accessing already created notifications using getScheduledLocalNotifications + * or getDeliveredNotifications. + */ +soundName?: ?string, + /** DEPRECATED. This was used for iOS's legacy UILocalNotification. */ + +alertAction?: ?string, |}; export interface Spec extends TurboModule { diff --git a/packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm b/packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm index 6237cfdaec384f..eb6e631a50f052 100644 --- a/packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm +++ b/packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm @@ -69,6 +69,10 @@ + (UILocalNotification *)UILocalNotification:(id)json return notification; } +@end + +@implementation RCTConvert (UIBackgroundFetchResult) + RCT_ENUM_CONVERTER( UIBackgroundFetchResult, (@{ @@ -89,6 +93,7 @@ @implementation RCTPushNotificationManager #if !TARGET_OS_UIKITFORMAC +/** DEPRECATED. UILocalNotification was deprecated in iOS 10. Please don't add new callsites. */ static NSDictionary *RCTFormatLocalNotification(UILocalNotification *notification) { NSMutableDictionary *formattedLocalNotification = [NSMutableDictionary dictionary]; @@ -108,27 +113,56 @@ @implementation RCTPushNotificationManager return formattedLocalNotification; } -static NSDictionary *RCTFormatUNNotification(UNNotification *notification) +/** For delivered notifications */ +static NSDictionary *RCTFormatUNNotification(UNNotification *notification) { - NSMutableDictionary *formattedNotification = [NSMutableDictionary dictionary]; - UNNotificationContent *content = notification.request.content; + NSMutableDictionary *formattedLocalNotification = [NSMutableDictionary dictionary]; + if (notification.date) { + formattedLocalNotification[@"fireDate"] = RCTFormatNotificationDateFromNSDate(notification.date); + } + [formattedLocalNotification addEntriesFromDictionary:RCTFormatUNNotificationContent(notification.request.content)]; + return formattedLocalNotification; +} - formattedNotification[@"identifier"] = notification.request.identifier; +/** For scheduled notification requests */ +static NSDictionary *RCTFormatUNNotificationRequest(UNNotificationRequest *request) +{ + NSMutableDictionary *formattedLocalNotification = [NSMutableDictionary dictionary]; + if (request.trigger) { + NSDate *triggerDate = nil; + if ([request.trigger isKindOfClass:[UNTimeIntervalNotificationTrigger class]]) { + triggerDate = [(UNTimeIntervalNotificationTrigger *)request.trigger nextTriggerDate]; + } else if ([request.trigger isKindOfClass:[UNCalendarNotificationTrigger class]]) { + triggerDate = [(UNCalendarNotificationTrigger *)request.trigger nextTriggerDate]; + } - if (notification.date) { - NSDateFormatter *formatter = [NSDateFormatter new]; - [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"]; - NSString *dateString = [formatter stringFromDate:notification.date]; - formattedNotification[@"date"] = dateString; + if (triggerDate) { + formattedLocalNotification[@"fireDate"] = RCTFormatNotificationDateFromNSDate(triggerDate); + } } + [formattedLocalNotification addEntriesFromDictionary:RCTFormatUNNotificationContent(request.content)]; + return formattedLocalNotification; +} - formattedNotification[@"title"] = RCTNullIfNil(content.title); - formattedNotification[@"body"] = RCTNullIfNil(content.body); - formattedNotification[@"category"] = RCTNullIfNil(content.categoryIdentifier); - formattedNotification[@"thread-id"] = RCTNullIfNil(content.threadIdentifier); - formattedNotification[@"userInfo"] = RCTNullIfNil(RCTJSONClean(content.userInfo)); +static NSDictionary *RCTFormatUNNotificationContent(UNNotificationContent *content) +{ + // Note: soundName is not set because this can't be read from UNNotificationSound. + // Note: alertAction is no longer relevant with UNNotification + NSMutableDictionary *formattedLocalNotification = [NSMutableDictionary dictionary]; + formattedLocalNotification[@"alertTitle"] = RCTNullIfNil(content.title); + formattedLocalNotification[@"alertBody"] = RCTNullIfNil(content.body); + formattedLocalNotification[@"userInfo"] = RCTNullIfNil(RCTJSONClean(content.userInfo)); + formattedLocalNotification[@"category"] = content.categoryIdentifier; + formattedLocalNotification[@"applicationIconBadgeNumber"] = content.badge; + formattedLocalNotification[@"remote"] = @NO; + return formattedLocalNotification; +} - return formattedNotification; +static NSString *RCTFormatNotificationDateFromNSDate(NSDate *date) +{ + NSDateFormatter *formatter = [NSDateFormatter new]; + [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"]; + return [formatter stringFromDate:date]; } #endif // TARGET_OS_UIKITFORMAC @@ -495,12 +529,14 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification RCT_EXPORT_METHOD(getScheduledLocalNotifications : (RCTResponseSenderBlock)callback) { - NSArray *scheduledLocalNotifications = RCTSharedApplication().scheduledLocalNotifications; - NSMutableArray *formattedScheduledLocalNotifications = [NSMutableArray new]; - for (UILocalNotification *notification in scheduledLocalNotifications) { - [formattedScheduledLocalNotifications addObject:RCTFormatLocalNotification(notification)]; - } - callback(@[ formattedScheduledLocalNotifications ]); + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center getPendingNotificationRequestsWithCompletionHandler:^(NSArray *_Nonnull requests) { + NSMutableArray *formattedScheduledLocalNotifications = [NSMutableArray new]; + for (UNNotificationRequest *request in requests) { + [formattedScheduledLocalNotifications addObject:RCTFormatUNNotificationRequest(request)]; + } + callback(@[ formattedScheduledLocalNotifications ]); + }]; } RCT_EXPORT_METHOD(removeAllDeliveredNotifications)