[notifications] Specific notificationPressed data type including action
This commit is contained in:
parent
303cb4c428
commit
8e84dd576b
|
@ -38,7 +38,7 @@ RCT_EXPORT_MODULE();
|
|||
- (void)configure {
|
||||
// If we're on iOS 10 then we need to set this as a delegate for the UNUserNotificationCenter
|
||||
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
// [UNUserNotificationCenter currentNotificationCenter].delegate = self;
|
||||
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
|
||||
#endif
|
||||
|
||||
// Set static instance for use from AppDelegate
|
||||
|
@ -51,6 +51,7 @@ RCT_EXPORT_MODULE();
|
|||
// *******************************************************
|
||||
|
||||
- (void)didReceiveLocalNotification:(nonnull UILocalNotification *)notification {
|
||||
#if !defined(__IPHONE_10_0) || __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_10_0
|
||||
NSString *event;
|
||||
if (RCTSharedApplication().applicationState == UIApplicationStateBackground) {
|
||||
// notification_displayed
|
||||
|
@ -65,6 +66,7 @@ RCT_EXPORT_MODULE();
|
|||
|
||||
NSDictionary *message = [self parseUILocalNotification:notification];
|
||||
[RNFirebaseUtil sendJSEvent:self name:event body:message];
|
||||
#endif
|
||||
}
|
||||
|
||||
// Listen for background messages
|
||||
|
@ -85,11 +87,16 @@ RCT_EXPORT_MODULE();
|
|||
event = NOTIFICATIONS_NOTIFICATION_PRESSED;
|
||||
} else {
|
||||
// notification_received
|
||||
// On IOS 10, foreground notifications also go through willPresentNotification
|
||||
// This prevents duplicate messages from hitting the JS app
|
||||
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
return;
|
||||
#else
|
||||
event = NOTIFICATIONS_NOTIFICATION_RECEIVED;
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: Proper notification structure
|
||||
NSDictionary *message = [self parseUserInfo:userInfo messageType:@"RemoteNotification" clickAction:nil];
|
||||
NSDictionary *message = [self parseUserInfo:userInfo messageType:@"RemoteNotification" category:nil];
|
||||
|
||||
[RNFirebaseUtil sendJSEvent:self name:event body:message];
|
||||
}
|
||||
|
@ -104,6 +111,7 @@ RCT_EXPORT_MODULE();
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
NSString *event;
|
||||
if (RCTSharedApplication().applicationState == UIApplicationStateBackground) {
|
||||
// notification_displayed
|
||||
|
@ -113,16 +121,19 @@ RCT_EXPORT_MODULE();
|
|||
event = NOTIFICATIONS_NOTIFICATION_PRESSED;
|
||||
} else {
|
||||
// notification_received
|
||||
// On IOS 10, foreground notifications also go through willPresentNotification
|
||||
// This prevents duplicate messages from hitting the JS app
|
||||
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
return;
|
||||
#else
|
||||
event = NOTIFICATIONS_NOTIFICATION_RECEIVED;
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: Proper notification structure
|
||||
NSDictionary *message = [self parseUserInfo:userInfo messageType:@"RemoteNotificationHandler" clickAction:nil];
|
||||
|
||||
// TODO: Callback handler
|
||||
// [_callbackHandlers setObject:[completionHandler copy] forKey:message[@"messageId"]];
|
||||
NSDictionary *message = [self parseUserInfo:userInfo messageType:@"RemoteNotificationHandler" category:nil];
|
||||
|
||||
[RNFirebaseUtil sendJSEvent:self name:event body:message];
|
||||
completionHandler(UIBackgroundFetchResultNoData);
|
||||
}
|
||||
|
||||
// *******************************************************
|
||||
|
@ -181,7 +192,7 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
|
|||
#else
|
||||
withCompletionHandler:(void(^)())completionHandler {
|
||||
#endif
|
||||
NSDictionary *message = [self parseUNNotification:response.notification messageType:@"NotificationResponse"];
|
||||
NSDictionary *message = [self parseUNNotificationResponse:response messageType:@"NotificationResponse"];
|
||||
|
||||
[RNFirebaseUtil sendJSEvent:self name:NOTIFICATIONS_NOTIFICATION_PRESSED body:message];
|
||||
completionHandler();
|
||||
|
@ -253,7 +264,7 @@ RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve rejecte
|
|||
} else {
|
||||
NSDictionary *remoteNotification = [self bridge].launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
|
||||
if (remoteNotification) {
|
||||
NSDictionary *message = [self parseUserInfo:remoteNotification messageType:@"InitialMessage" clickAction:nil];
|
||||
NSDictionary *message = [self parseUserInfo:remoteNotification messageType:@"InitialMessage" category:nil];
|
||||
resolve(message);
|
||||
} else {
|
||||
resolve(nil);
|
||||
|
@ -560,17 +571,27 @@ RCT_EXPORT_METHOD(scheduleNotification:(NSDictionary*) notification
|
|||
return notification;
|
||||
}
|
||||
|
||||
- (NSDictionary*)parseUNNotificationResponse:(UNNotificationResponse *)response
|
||||
messageType:(NSString *)messageType {
|
||||
NSMutableDictionary *notificationResponse = [[NSMutableDictionary alloc] init];
|
||||
NSDictionary *notification = [self parseUNNotification:response.notification messageType:messageType];
|
||||
notificationResponse[@"notification"] = notification;
|
||||
notificationResponse[@"action"] = response.actionIdentifier;
|
||||
|
||||
return notificationResponse;
|
||||
}
|
||||
|
||||
- (NSDictionary*)parseUNNotification:(UNNotification *)notification
|
||||
messageType:(NSString *)messageType {
|
||||
NSDictionary *userInfo = notification.request.content.userInfo;
|
||||
NSString *clickAction = notification.request.content.categoryIdentifier;
|
||||
NSString *category = notification.request.content.categoryIdentifier;
|
||||
|
||||
return [self parseUserInfo:userInfo messageType:messageType clickAction:clickAction];
|
||||
return [self parseUserInfo:userInfo messageType:messageType category:category];
|
||||
}
|
||||
|
||||
- (NSDictionary*)parseUserInfo:(NSDictionary *)userInfo
|
||||
messageType:(NSString *) messageType
|
||||
clickAction:(NSString *) clickAction {
|
||||
category:(NSString *) category {
|
||||
|
||||
NSMutableDictionary *notification = [[NSMutableDictionary alloc] init];
|
||||
NSMutableDictionary *data = [[NSMutableDictionary alloc] init];
|
||||
|
@ -585,22 +606,15 @@ RCT_EXPORT_METHOD(scheduleNotification:(NSDictionary*) notification
|
|||
for (id k3 in alert) {
|
||||
if ([k3 isEqualToString:@"body"]) {
|
||||
notification[@"body"] = alert[k3];
|
||||
} else if ([k3 isEqualToString:@"loc-args"]) {
|
||||
// TODO: What to do with this?
|
||||
// notif[@"bodyLocalizationArgs"] = alert[k3];
|
||||
} else if ([k3 isEqualToString:@"loc-key"]) {
|
||||
// TODO: What to do with this?
|
||||
// notif[@"bodyLocalizationKey"] = alert[k3];
|
||||
} else if ([k3 isEqualToString:@"subtitle"]) {
|
||||
notification[@"subtitle"] = alert[k3];
|
||||
} else if ([k3 isEqualToString:@"title"]) {
|
||||
notification[@"title"] = alert[k3];
|
||||
} else if ([k3 isEqualToString:@"title-loc-args"]) {
|
||||
// TODO: What to do with this?
|
||||
// notif[@"titleLocalizationArgs"] = alert[k3];
|
||||
} else if ([k3 isEqualToString:@"title-loc-key"]) {
|
||||
// TODO: What to do with this?
|
||||
// notif[@"titleLocalizationKey"] = alert[k3];
|
||||
} else if ([k3 isEqualToString:@"loc-args"]
|
||||
|| [k3 isEqualToString:@"loc-key"]
|
||||
|| [k3 isEqualToString:@"title-loc-args"]
|
||||
|| [k3 isEqualToString:@"title-loc-key"]) {
|
||||
// Ignore known keys
|
||||
} else {
|
||||
NSLog(@"Unknown alert key: %@", k2);
|
||||
}
|
||||
|
@ -617,15 +631,13 @@ RCT_EXPORT_METHOD(scheduleNotification:(NSDictionary*) notification
|
|||
}
|
||||
} else if ([k1 isEqualToString:@"gcm.message_id"]) {
|
||||
notification[@"notificationId"] = userInfo[k1];
|
||||
} else if ([k1 isEqualToString:@"google.c.a.ts"]) {
|
||||
// TODO: What to do with this?
|
||||
// message[@"sentTime"] = userInfo[k1];
|
||||
} else if ([k1 isEqualToString:@"gcm.n.e"]
|
||||
|| [k1 isEqualToString:@"gcm.notification.sound2"]
|
||||
|| [k1 isEqualToString:@"google.c.a.c_id"]
|
||||
|| [k1 isEqualToString:@"google.c.a.c_l"]
|
||||
|| [k1 isEqualToString:@"google.c.a.e"]
|
||||
|| [k1 isEqualToString:@"google.c.a.udt"]) {
|
||||
|| [k1 isEqualToString:@"google.c.a.udt"]
|
||||
|| [k1 isEqualToString:@"google.c.a.ts"]) {
|
||||
// Ignore known keys
|
||||
} else {
|
||||
// Assume custom data
|
||||
|
@ -633,6 +645,10 @@ RCT_EXPORT_METHOD(scheduleNotification:(NSDictionary*) notification
|
|||
}
|
||||
}
|
||||
|
||||
if (!ios[@"category"]) {
|
||||
ios[@"category"] = category;
|
||||
}
|
||||
|
||||
// TODO: What to do with this?
|
||||
// message[@"messageType"] = messageType;
|
||||
|
||||
|
|
|
@ -9,6 +9,11 @@ import { generatePushID, isObject } from '../../utils';
|
|||
|
||||
import type { NativeNotification } from './types';
|
||||
|
||||
export type NotificationPressed = {
|
||||
action: string,
|
||||
notification: Notification,
|
||||
};
|
||||
|
||||
export default class Notification {
|
||||
// iOS 8/9 | 10+ | Android
|
||||
_android: AndroidNotification;
|
||||
|
|
|
@ -18,7 +18,12 @@ import {
|
|||
} from './types';
|
||||
|
||||
import type App from '../core/app';
|
||||
import type { NativeNotification, Schedule } from './types';
|
||||
import type { NotificationPressed } from './Notification';
|
||||
import type {
|
||||
NativeNotification,
|
||||
NativeNotificationPressed,
|
||||
Schedule,
|
||||
} from './types';
|
||||
|
||||
type OnNotification = Notification => any;
|
||||
|
||||
|
@ -26,6 +31,12 @@ type OnNotificationObserver = {
|
|||
next: OnNotification,
|
||||
};
|
||||
|
||||
type OnNotificationPressed = NotificationPressed => any;
|
||||
|
||||
type OnNotificationPressedObserver = {
|
||||
next: OnNotificationPressed,
|
||||
};
|
||||
|
||||
const NATIVE_EVENTS = [
|
||||
'notifications_notification_displayed',
|
||||
'notifications_notification_pressed',
|
||||
|
@ -61,18 +72,6 @@ export default class Notifications extends ModuleBase {
|
|||
namespace: NAMESPACE,
|
||||
});
|
||||
|
||||
SharedEventEmitter.addListener(
|
||||
// sub to internal native event - this fans out to
|
||||
// public event name: onNotificationPressed
|
||||
'notifications_notification_pressed',
|
||||
(notification: NativeNotification) => {
|
||||
SharedEventEmitter.emit(
|
||||
'onNotificationPressed',
|
||||
new Notification(notification)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
SharedEventEmitter.addListener(
|
||||
// sub to internal native event - this fans out to
|
||||
// public event name: onNotificationDisplayed
|
||||
|
@ -85,6 +84,18 @@ export default class Notifications extends ModuleBase {
|
|||
}
|
||||
);
|
||||
|
||||
SharedEventEmitter.addListener(
|
||||
// sub to internal native event - this fans out to
|
||||
// public event name: onNotificationPressed
|
||||
'notifications_notification_pressed',
|
||||
(notificationPressed: NativeNotificationPressed) => {
|
||||
SharedEventEmitter.emit('onNotificationPressed', {
|
||||
action: notificationPressed.action,
|
||||
notification: new Notification(notificationPressed.notification),
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
SharedEventEmitter.addListener(
|
||||
// sub to internal native event - this fans out to
|
||||
// public event name: onNotification
|
||||
|
@ -193,11 +204,10 @@ export default class Notifications extends ModuleBase {
|
|||
}
|
||||
|
||||
onNotificationPressed(
|
||||
nextOrObserver: OnNotification | OnNotificationObserver
|
||||
nextOrObserver: OnNotificationPressed | OnNotificationPressedObserver
|
||||
): () => any {
|
||||
let listener: Notification => any;
|
||||
let listener;
|
||||
if (isFunction(nextOrObserver)) {
|
||||
// $FlowBug: Not coping with the overloaded method signature
|
||||
listener = nextOrObserver;
|
||||
} else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) {
|
||||
listener = nextOrObserver.next;
|
||||
|
|
|
@ -160,3 +160,8 @@ export type NativeNotification = {|
|
|||
subtitle?: string,
|
||||
title: string,
|
||||
|};
|
||||
|
||||
export type NativeNotificationPressed = {|
|
||||
action: string,
|
||||
notification: NativeNotification,
|
||||
|};
|
||||
|
|
Loading…
Reference in New Issue