Skip to content

Commit 3923330

Browse files
ingridwangSaadnajmi
authored andcommitted
Migrate getScheduledLocalNotifications off of deprecated UILocalNotification (facebook#40948)
Summary: Pull Request resolved: facebook#40948 [iOS][Breaking] alertAction is deprecated in PushNotificationIOS. getScheduledLocalNotifications now uses new iOS APIs which do not expose this property. Reviewed By: cipolleschi Differential Revision: D50275541 fbshipit-source-id: e4ecad858cd06350c749e7f5a837f36316656183
1 parent ae18bd9 commit 3923330

2 files changed

Lines changed: 84 additions & 50 deletions

File tree

packages/react-native/Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,20 @@ type Notification = {|
2323
// Actual type: string | number
2424
+fireDate?: ?number,
2525
+alertBody?: ?string,
26-
+alertAction?: ?string,
2726
+userInfo?: ?Object,
2827
+category?: ?string,
2928
// Actual type: 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute'
3029
+repeatInterval?: ?string,
3130
+applicationIconBadgeNumber?: ?number,
3231
+isSilent?: ?boolean,
32+
/**
33+
* Custom notification sound to play. Write-only: soundName will be null when
34+
* accessing already created notifications using getScheduledLocalNotifications
35+
* or getDeliveredNotifications.
36+
*/
3337
+soundName?: ?string,
38+
/** DEPRECATED. This was used for iOS's legacy UILocalNotification. */
39+
+alertAction?: ?string,
3440
|};
3541

3642
export interface Spec extends TurboModule {

packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm

Lines changed: 77 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ + (NSUserNotification *)NSUserNotification:(id)json
106106
}
107107
#endif // macOS]
108108

109+
@end
110+
109111
#if !TARGET_OS_OSX // [macOS]
112+
@implementation RCTConvert (UIBackgroundFetchResult)
113+
110114
RCT_ENUM_CONVERTER(
111115
UIBackgroundFetchResult,
112116
(@{
@@ -116,18 +120,20 @@ + (NSUserNotification *)NSUserNotification:(id)json
116120
}),
117121
UIBackgroundFetchResultNoData,
118122
integerValue)
119-
#endif // [macOS]
120123

121124
@end
125+
#endif // [macOS]
122126
#else
123127
@interface RCTPushNotificationManager () <NativePushNotificationManagerIOSSpec>
124128
@end
125129
#endif // TARGET_OS_UIKITFORMAC
126130

127131
@implementation RCTPushNotificationManager
128132

129-
#if !TARGET_OS_UIKITFORMAC && !TARGET_OS_OSX // [macOS]
133+
#if !TARGET_OS_UIKITFORMAC
130134

135+
#if !TARGET_OS_OSX // [macOS]
136+
/** DEPRECATED. UILocalNotification was deprecated in iOS 10. Please don't add new callsites. */
131137
static NSDictionary *RCTFormatLocalNotification(UILocalNotification *notification)
132138
{
133139
NSMutableDictionary *formattedLocalNotification = [NSMutableDictionary dictionary];
@@ -146,41 +152,15 @@ @implementation RCTPushNotificationManager
146152
formattedLocalNotification[@"remote"] = @NO;
147153
return formattedLocalNotification;
148154
}
149-
150-
static NSDictionary *RCTFormatUNNotification(UNNotification *notification)
151-
{
152-
NSMutableDictionary *formattedNotification = [NSMutableDictionary dictionary];
153-
UNNotificationContent *content = notification.request.content;
154-
155-
formattedNotification[@"identifier"] = notification.request.identifier;
156-
157-
if (notification.date) {
158-
NSDateFormatter *formatter = [NSDateFormatter new];
159-
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"];
160-
NSString *dateString = [formatter stringFromDate:notification.date];
161-
formattedNotification[@"date"] = dateString;
162-
}
163-
164-
formattedNotification[@"title"] = RCTNullIfNil(content.title);
165-
formattedNotification[@"body"] = RCTNullIfNil(content.body);
166-
formattedNotification[@"category"] = RCTNullIfNil(content.categoryIdentifier);
167-
formattedNotification[@"thread-id"] = RCTNullIfNil(content.threadIdentifier);
168-
formattedNotification[@"userInfo"] = RCTNullIfNil(RCTJSONClean(content.userInfo));
169-
170-
return formattedNotification;
171-
}
172-
173-
#endif // TARGET_OS_UIKITFORMAC
174-
#if TARGET_OS_OSX // [macOS
175-
155+
#else // [macOS
176156
static NSDictionary *RCTFormatUserNotification(NSUserNotification *notification)
177157
{
178158
NSMutableDictionary *formattedUserNotification = [NSMutableDictionary dictionary];
179159
if (notification.deliveryDate) {
180-
NSDateFormatter *formatter = [NSDateFormatter new];
181-
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"];
182-
NSString *fireDateString = [formatter stringFromDate:notification.deliveryDate];
183-
formattedUserNotification[@"fireDate"] = fireDateString;
160+
NSDateFormatter *formatter = [NSDateFormatter new];
161+
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"];
162+
NSString *fireDateString = [formatter stringFromDate:notification.deliveryDate];
163+
formattedUserNotification[@"fireDate"] = fireDateString;
184164
}
185165
formattedUserNotification[@"alertAction"] = RCTNullIfNil(notification.actionButtonTitle);
186166
formattedUserNotification[@"alertBody"] = RCTNullIfNil(notification.informativeText);
@@ -192,6 +172,60 @@ @implementation RCTPushNotificationManager
192172
}
193173
#endif // macOS]
194174

175+
/** For delivered notifications */
176+
static NSDictionary<NSString *, id> *RCTFormatUNNotification(UNNotification *notification)
177+
{
178+
NSMutableDictionary *formattedLocalNotification = [NSMutableDictionary dictionary];
179+
if (notification.date) {
180+
formattedLocalNotification[@"fireDate"] = RCTFormatNotificationDateFromNSDate(notification.date);
181+
}
182+
[formattedLocalNotification addEntriesFromDictionary:RCTFormatUNNotificationContent(notification.request.content)];
183+
return formattedLocalNotification;
184+
}
185+
186+
/** For scheduled notification requests */
187+
static NSDictionary<NSString *, id> *RCTFormatUNNotificationRequest(UNNotificationRequest *request)
188+
{
189+
NSMutableDictionary *formattedLocalNotification = [NSMutableDictionary dictionary];
190+
if (request.trigger) {
191+
NSDate *triggerDate = nil;
192+
if ([request.trigger isKindOfClass:[UNTimeIntervalNotificationTrigger class]]) {
193+
triggerDate = [(UNTimeIntervalNotificationTrigger *)request.trigger nextTriggerDate];
194+
} else if ([request.trigger isKindOfClass:[UNCalendarNotificationTrigger class]]) {
195+
triggerDate = [(UNCalendarNotificationTrigger *)request.trigger nextTriggerDate];
196+
}
197+
198+
if (triggerDate) {
199+
formattedLocalNotification[@"fireDate"] = RCTFormatNotificationDateFromNSDate(triggerDate);
200+
}
201+
}
202+
[formattedLocalNotification addEntriesFromDictionary:RCTFormatUNNotificationContent(request.content)];
203+
return formattedLocalNotification;
204+
}
205+
206+
static NSDictionary<NSString *, id> *RCTFormatUNNotificationContent(UNNotificationContent *content)
207+
{
208+
// Note: soundName is not set because this can't be read from UNNotificationSound.
209+
// Note: alertAction is no longer relevant with UNNotification
210+
NSMutableDictionary *formattedLocalNotification = [NSMutableDictionary dictionary];
211+
formattedLocalNotification[@"alertTitle"] = RCTNullIfNil(content.title);
212+
formattedLocalNotification[@"alertBody"] = RCTNullIfNil(content.body);
213+
formattedLocalNotification[@"userInfo"] = RCTNullIfNil(RCTJSONClean(content.userInfo));
214+
formattedLocalNotification[@"category"] = content.categoryIdentifier;
215+
formattedLocalNotification[@"applicationIconBadgeNumber"] = content.badge;
216+
formattedLocalNotification[@"remote"] = @NO;
217+
return formattedLocalNotification;
218+
}
219+
220+
static NSString *RCTFormatNotificationDateFromNSDate(NSDate *date)
221+
{
222+
NSDateFormatter *formatter = [NSDateFormatter new];
223+
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"];
224+
return [formatter stringFromDate:date];
225+
}
226+
227+
#endif // TARGET_OS_UIKITFORMAC
228+
195229
RCT_EXPORT_MODULE()
196230

197231
- (dispatch_queue_t)methodQueue
@@ -337,9 +371,9 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification
337371
[self sendEventWithName:@"remoteNotificationRegistrationError" body:errorDetails];
338372
}
339373

340-
#if !TARGET_OS_OSX // [macOS]
341374
RCT_EXPORT_METHOD(onFinishRemoteNotification : (NSString *)notificationId fetchResult : (NSString *)fetchResult)
342375
{
376+
#if !TARGET_OS_OSX // [macOS]
343377
UIBackgroundFetchResult result = [RCTConvert UIBackgroundFetchResult:fetchResult];
344378
RCTRemoteNotificationCallback completionHandler = self.remoteNotificationCallbacks[notificationId];
345379
if (!completionHandler) {
@@ -348,8 +382,8 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification
348382
}
349383
completionHandler(result);
350384
[self.remoteNotificationCallbacks removeObjectForKey:notificationId];
351-
}
352385
#endif // [macOS]
386+
}
353387

354388
/**
355389
* Update the application icon badge number on the home screen
@@ -610,20 +644,14 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification
610644

611645
RCT_EXPORT_METHOD(getScheduledLocalNotifications : (RCTResponseSenderBlock)callback)
612646
{
613-
#if !TARGET_OS_OSX // [macOS]
614-
NSArray<UILocalNotification *> *scheduledLocalNotifications = RCTSharedApplication().scheduledLocalNotifications;
615-
#endif // [macOS]
616-
NSMutableArray<NSDictionary *> *formattedScheduledLocalNotifications = [NSMutableArray new];
617-
#if !TARGET_OS_OSX // [macOS]
618-
for (UILocalNotification *notification in scheduledLocalNotifications) {
619-
[formattedScheduledLocalNotifications addObject:RCTFormatLocalNotification(notification)];
620-
}
621-
#else // [macOS
622-
for (NSUserNotification *notification in [NSUserNotificationCenter defaultUserNotificationCenter].scheduledNotifications) {
623-
[formattedScheduledLocalNotifications addObject:RCTFormatUserNotification(notification)];
624-
}
625-
#endif // macOS]
626-
callback(@[ formattedScheduledLocalNotifications ]);
647+
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
648+
[center getPendingNotificationRequestsWithCompletionHandler:^(NSArray<UNNotificationRequest *> *_Nonnull requests) {
649+
NSMutableArray<NSDictionary *> *formattedScheduledLocalNotifications = [NSMutableArray new];
650+
for (UNNotificationRequest *request in requests) {
651+
[formattedScheduledLocalNotifications addObject:RCTFormatUNNotificationRequest(request)];
652+
}
653+
callback(@[ formattedScheduledLocalNotifications ]);
654+
}];
627655
}
628656

629657
RCT_EXPORT_METHOD(removeAllDeliveredNotifications)

0 commit comments

Comments
 (0)