Correctly passes localNotification to app on wakeup
Summary: Currently if an RN app is started in response to a remote notification, that notification's data is available on startup via `PushNotificationIOS.popInitialNotification()`. However, if the app is started in response to a "local" notification, that information is never passed in. This PR modifies the `popInitialNotification` behavior so it will return the notification used to launch the app, no matter if it was local or remote. I've tested this change in my app and ensured that when the app is woken up with a `localNotification` it's passed in to `PushNotificationIOS.popInitialNotification`. I've also tested that the `localNotification` event continues working as before. Closes https://github.com/facebook/react-native/pull/7765 Differential Revision: D3417267 Pulled By: nicklockwood fbshipit-source-id: 0b5b432e9a75dda7d3c50289a3bf0f1c1ffcf061
This commit is contained in:
parent
6236a593d8
commit
57d45235ec
|
@ -31,10 +31,6 @@ NSString *const RCTRegisterUserNotificationSettings = @"RegisterUserNotification
|
|||
|
||||
NSString *const RCTErrorUnableToRequestPermissions = @"E_UNABLE_TO_REQUEST_PERMISSIONS";
|
||||
|
||||
@interface RCTPushNotificationManager ()
|
||||
@property (nonatomic, copy) RCTPromiseResolveBlock requestPermissionsResolveBlock;
|
||||
@end
|
||||
|
||||
@implementation RCTConvert (UILocalNotification)
|
||||
|
||||
+ (UILocalNotification *)UILocalNotification:(id)json
|
||||
|
@ -56,12 +52,15 @@ NSString *const RCTErrorUnableToRequestPermissions = @"E_UNABLE_TO_REQUEST_PERMI
|
|||
@end
|
||||
|
||||
@implementation RCTPushNotificationManager
|
||||
{
|
||||
RCTPromiseResolveBlock _requestPermissionsResolveBlock;
|
||||
}
|
||||
|
||||
static NSDictionary *formatLocalNotification(UILocalNotification *notification)
|
||||
static NSDictionary *RCTFormatLocalNotification(UILocalNotification *notification)
|
||||
{
|
||||
NSMutableDictionary *formattedLocalNotification = [NSMutableDictionary dictionary];
|
||||
if (notification.fireDate) {
|
||||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||||
NSDateFormatter *formatter = [NSDateFormatter new];
|
||||
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"];
|
||||
NSString *fireDateString = [formatter stringFromDate:notification.fireDate];
|
||||
formattedLocalNotification[@"fireDate"] = fireDateString;
|
||||
|
@ -77,6 +76,11 @@ static NSDictionary *formatLocalNotification(UILocalNotification *notification)
|
|||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (dispatch_queue_t)methodQueue
|
||||
{
|
||||
return dispatch_get_main_queue();
|
||||
}
|
||||
|
||||
- (void)startObserving
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
|
@ -114,8 +118,18 @@ RCT_EXPORT_MODULE()
|
|||
- (NSDictionary<NSString *, id> *)constantsToExport
|
||||
{
|
||||
NSDictionary<NSString *, id> *initialNotification =
|
||||
[self.bridge.launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] copy];
|
||||
return @{@"initialNotification": RCTNullIfNil(initialNotification)};
|
||||
self.bridge.launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
|
||||
|
||||
UILocalNotification *initialLocalNotification =
|
||||
self.bridge.launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
|
||||
|
||||
if (initialNotification) {
|
||||
return @{@"initialNotification": [initialNotification copy]};
|
||||
} else if (initialLocalNotification) {
|
||||
return @{@"initialNotification": RCTFormatLocalNotification(initialLocalNotification)};
|
||||
} else {
|
||||
return @{@"initialNotification": (id)kCFNull};
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)didRegisterUserNotificationSettings:(__unused UIUserNotificationSettings *)notificationSettings
|
||||
|
@ -150,16 +164,9 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
+ (void)didReceiveLocalNotification:(UILocalNotification *)notification
|
||||
{
|
||||
NSMutableDictionary *details = [NSMutableDictionary new];
|
||||
if (notification.alertBody) {
|
||||
details[@"alertBody"] = notification.alertBody;
|
||||
}
|
||||
if (notification.userInfo) {
|
||||
details[@"userInfo"] = RCTJSONClean(notification.userInfo);
|
||||
}
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTLocalNotificationReceived
|
||||
object:self
|
||||
userInfo:details];
|
||||
userInfo:RCTFormatLocalNotification(notification)];
|
||||
}
|
||||
|
||||
- (void)handleLocalNotificationReceived:(NSNotification *)notification
|
||||
|
@ -179,7 +186,7 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
- (void)handleRegisterUserNotificationSettings:(NSNotification *)notification
|
||||
{
|
||||
if (self.requestPermissionsResolveBlock == nil) {
|
||||
if (_requestPermissionsResolveBlock == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -190,8 +197,8 @@ RCT_EXPORT_MODULE()
|
|||
@"badge": @((notificationSettings.types & UIUserNotificationTypeBadge) > 0),
|
||||
};
|
||||
|
||||
self.requestPermissionsResolveBlock(notificationTypes);
|
||||
self.requestPermissionsResolveBlock = nil;
|
||||
_requestPermissionsResolveBlock(notificationTypes);
|
||||
_requestPermissionsResolveBlock = nil;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -219,12 +226,12 @@ RCT_EXPORT_METHOD(requestPermissions:(NSDictionary *)permissions
|
|||
return;
|
||||
}
|
||||
|
||||
if (self.requestPermissionsResolveBlock != nil) {
|
||||
if (_requestPermissionsResolveBlock != nil) {
|
||||
RCTLogError(@"Cannot call requestPermissions twice before the first has returned.");
|
||||
return;
|
||||
}
|
||||
|
||||
self.requestPermissionsResolveBlock = resolve;
|
||||
_requestPermissionsResolveBlock = resolve;
|
||||
|
||||
UIUserNotificationType types = UIUserNotificationTypeNone;
|
||||
if (permissions) {
|
||||
|
@ -298,11 +305,15 @@ RCT_EXPORT_METHOD(cancelAllLocalNotifications)
|
|||
[RCTSharedApplication() cancelAllLocalNotifications];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(cancelLocalNotifications:(NSDictionary *)userInfo)
|
||||
RCT_EXPORT_METHOD(cancelLocalNotifications:(NSDictionary<NSString *, id> *)userInfo)
|
||||
{
|
||||
for (UILocalNotification *notification in [UIApplication sharedApplication].scheduledLocalNotifications) {
|
||||
__block BOOL matchesAll = YES;
|
||||
NSDictionary *notificationInfo = notification.userInfo;
|
||||
NSDictionary<NSString *, id> *notificationInfo = notification.userInfo;
|
||||
// Note: we do this with a loop instead of just `isEqualToDictionary:`
|
||||
// because we only require that all specified userInfo values match the
|
||||
// notificationInfo values - notificationInfo may contain additional values
|
||||
// which we don't care about.
|
||||
[userInfo enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
|
||||
if (![notificationInfo[key] isEqual:obj]) {
|
||||
matchesAll = NO;
|
||||
|
@ -319,16 +330,26 @@ RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve
|
|||
reject:(__unused RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
NSDictionary<NSString *, id> *initialNotification =
|
||||
[self.bridge.launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] copy];
|
||||
resolve(RCTNullIfNil(initialNotification));
|
||||
self.bridge.launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
|
||||
|
||||
UILocalNotification *initialLocalNotification =
|
||||
self.bridge.launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
|
||||
|
||||
if (initialNotification) {
|
||||
resolve([initialNotification copy]);
|
||||
} else if (initialLocalNotification) {
|
||||
resolve(RCTFormatLocalNotification(initialLocalNotification));
|
||||
} else {
|
||||
resolve((id)kCFNull);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getScheduledLocalNotifications:(RCTResponseSenderBlock)callback)
|
||||
{
|
||||
NSArray<UILocalNotification *> *scheduledLocalNotifications = [UIApplication sharedApplication].scheduledLocalNotifications;
|
||||
NSMutableArray *formattedScheduledLocalNotifications = [[NSMutableArray alloc] init];
|
||||
NSMutableArray<NSDictionary *> *formattedScheduledLocalNotifications = [NSMutableArray new];
|
||||
for (UILocalNotification *notification in scheduledLocalNotifications) {
|
||||
[formattedScheduledLocalNotifications addObject:formatLocalNotification(notification)];
|
||||
[formattedScheduledLocalNotifications addObject:RCTFormatLocalNotification(notification)];
|
||||
}
|
||||
callback(@[formattedScheduledLocalNotifications]);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue