From 138636054e65b0dfa41fbf835ca3ae8b4e518cf7 Mon Sep 17 00:00:00 2001 From: yogevbd Date: Tue, 9 Jul 2019 13:10:31 +0300 Subject: [PATCH] Fix pushKit --- RNNotifications/RNCommandsHandler.m | 2 +- RNNotifications/RNEventEmitter.h | 1 + RNNotifications/RNEventEmitter.m | 3 +- RNNotifications/RNNotifications.h | 10 ++-- RNNotifications/RNNotifications.m | 28 +++++++---- RNNotifications/RNPushKitEventHandler.h | 2 + RNNotifications/RNPushKitEventHandler.m | 4 ++ RNNotifications/RNPushKitEventListener.m | 2 +- docs/advancedIos.md | 48 ++++--------------- docs/notificationsEvents.md | 1 - example/index.ios.js | 9 ++-- .../ios/NotificationsExampleApp/AppDelegate.m | 11 ++--- lib/src/index.ios.js | 11 ++++- lib/src/notification.ios.js | 24 +++++----- 14 files changed, 76 insertions(+), 80 deletions(-) diff --git a/RNNotifications/RNCommandsHandler.m b/RNNotifications/RNCommandsHandler.m index 5544089..7509e38 100644 --- a/RNNotifications/RNCommandsHandler.m +++ b/RNNotifications/RNCommandsHandler.m @@ -33,7 +33,7 @@ } - (void)registerPushKit { - [[RNNotifications sharedInstance] initializePushKit]; + [RNNotifications startMonitorPushKitNotifications]; } - (void)getBadgesCount:(RCTResponseSenderBlock)callback { diff --git a/RNNotifications/RNEventEmitter.h b/RNNotifications/RNEventEmitter.h index 1e7239b..011477d 100644 --- a/RNNotifications/RNEventEmitter.h +++ b/RNNotifications/RNEventEmitter.h @@ -5,6 +5,7 @@ static NSString* const RNRegistrationFailed = @"remoteNotificationsR static NSString* const RNPushKitRegistered = @"pushKitRegistered"; static NSString* const RNNotificationReceivedForeground = @"notificationReceivedForeground"; static NSString* const RNNotificationOpened = @"notificationOpened"; +static NSString* const RNPushKitNotificationReceived = @"pushKitNotificationReceived"; @interface RNEventEmitter : RCTEventEmitter diff --git a/RNNotifications/RNEventEmitter.m b/RNNotifications/RNEventEmitter.m index 9078003..c5764b1 100644 --- a/RNNotifications/RNEventEmitter.m +++ b/RNNotifications/RNEventEmitter.m @@ -9,7 +9,8 @@ RCT_EXPORT_MODULE(); RNRegistrationFailed, RNPushKitRegistered, RNNotificationReceivedForeground, - RNNotificationOpened]; + RNNotificationOpened, + RNPushKitNotificationReceived]; } - (instancetype)init { diff --git a/RNNotifications/RNNotifications.h b/RNNotifications/RNNotifications.h index c470456..3462e1d 100644 --- a/RNNotifications/RNNotifications.h +++ b/RNNotifications/RNNotifications.h @@ -8,14 +8,14 @@ + (instancetype)sharedInstance; -- (void)initialize; -- (void)initializePushKit; ++ (void)startMonitorNotifications; ++ (void)startMonitorPushKitNotifications; + ++ (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken; ++ (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error; -- (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken; -- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error; - (void)finishHandleNotificationKey:(NSString *)notificationKey presentingOptions:(UNNotificationPresentationOptions)presentingOptions; - (void)finishHandleActionKey:(NSString *)actionKey; -//- (void)setBadgeForNotification:(NSDictionary *)notification; @end diff --git a/RNNotifications/RNNotifications.m b/RNNotifications/RNNotifications.m index 35e5b42..c94cf03 100644 --- a/RNNotifications/RNNotifications.m +++ b/RNNotifications/RNNotifications.m @@ -18,6 +18,7 @@ - (instancetype)init { self = [super init]; _store = [RNNotificationsStore new]; + _notificationEventHandler = [[RNNotificationEventHandler alloc] initWithStore:_store]; return self; } @@ -31,12 +32,27 @@ return sharedInstance; } -- (void)initialize { - _notificationEventHandler = [[RNNotificationEventHandler alloc] initWithStore:_store]; ++ (void)startMonitorNotifications { + [[self sharedInstance] startMonitorNotifications]; +} + ++ (void)startMonitorPushKitNotifications { + [[self sharedInstance] startMonitorPushKitNotifications]; +} + ++ (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken { + [[self sharedInstance] didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; +} + ++ (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { + [[self sharedInstance] didFailToRegisterForRemoteNotificationsWithError:error]; +} + +- (void)startMonitorNotifications { _notificationCenterListener = [[RNNotificationCenterListener alloc] initWithNotificationEventHandler:_notificationEventHandler]; } -- (void)initializePushKit { +- (void)startMonitorPushKitNotifications { _pushKitEventHandler = [RNPushKitEventHandler new]; _pushKit = [[RNPushKit alloc] initWithEventHandler:_pushKitEventHandler]; } @@ -49,12 +65,6 @@ [_notificationEventHandler didFailToRegisterForRemoteNotificationsWithError:error]; } -- (void)setBadgeForNotification:(NSDictionary *)notification { - if ([[notification objectForKey:@"aps"] objectForKey:@"badge"]){ - [[UIApplication sharedApplication] setApplicationIconBadgeNumber:[[[notification objectForKey:@"aps"] objectForKey:@"badge"] intValue]]; - } -} - - (void)setInitialNotification:(NSDictionary *)notification { [_store setInitialNotification:notification]; } diff --git a/RNNotifications/RNPushKitEventHandler.h b/RNNotifications/RNPushKitEventHandler.h index c1c0a38..e627cd2 100644 --- a/RNNotifications/RNPushKitEventHandler.h +++ b/RNNotifications/RNPushKitEventHandler.h @@ -5,4 +5,6 @@ - (void)registeredWithToken:(NSString *)token; +- (void)didReceiveIncomingPushWithPayload:(NSDictionary *)payload; + @end diff --git a/RNNotifications/RNPushKitEventHandler.m b/RNNotifications/RNPushKitEventHandler.m index ed27d83..2e2c99e 100644 --- a/RNNotifications/RNPushKitEventHandler.m +++ b/RNNotifications/RNPushKitEventHandler.m @@ -7,4 +7,8 @@ [RNEventEmitter sendEvent:RNPushKitRegistered body:@{@"pushKitToken": token}]; } +- (void)didReceiveIncomingPushWithPayload:(NSDictionary *)payload { + [RNEventEmitter sendEvent:RNPushKitNotificationReceived body:payload]; +} + @end diff --git a/RNNotifications/RNPushKitEventListener.m b/RNNotifications/RNPushKitEventListener.m index 086fcd2..65e18fe 100644 --- a/RNNotifications/RNPushKitEventListener.m +++ b/RNNotifications/RNPushKitEventListener.m @@ -20,7 +20,7 @@ } - (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type { -// [_pushKitEventHandler didOpenNotificationPayload:payload.dictionaryPayload]; + [_pushKitEventHandler didReceiveIncomingPushWithPayload:payload.dictionaryPayload]; } @end diff --git a/docs/advancedIos.md b/docs/advancedIos.md index ef272c2..584a28e 100644 --- a/docs/advancedIos.md +++ b/docs/advancedIos.md @@ -150,22 +150,7 @@ Notification **actions** allow the user to interact with a given notification. Notification **categories** allow you to group multiple actions together, and to connect the actions with the push notification itself. -In order to support interactive notifications, firstly add the following methods to `appDelegate.m` file: - -```objective-c -// Required for the notification actions. -- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler -{ - [RNNotifications handleActionWithIdentifier:identifier forLocalNotification:notification withResponseInfo:responseInfo completionHandler:completionHandler]; -} - -- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler -{ - [RNNotifications handleActionWithIdentifier:identifier forRemoteNotification:userInfo withResponseInfo:responseInfo completionHandler:completionHandler]; -} -``` - -Then, follow the basic workflow of adding interactive notifications to your app: +Follow the basic workflow of adding interactive notifications to your app: 1. Config the actions. 2. Group actions together into categories. @@ -187,25 +172,13 @@ let upvoteAction = new NotificationAction({ buttonTitle: 'title', placeholder: 'placeholder text' } -}, (action, completed) => { - console.log("ACTION RECEIVED"); - console.log(JSON.stringify(action)); - - // You must call to completed(), otherwise the action will not be triggered - completed(); }); let replyAction = new NotificationAction({ activationMode: "background", title: "Reply", - behavior: "textInput", authenticationRequired: true, identifier: "REPLY_ACTION" -}, (action, completed) => { - console.log("ACTION RECEIVED"); - console.log(action); - - completed(); }); ``` @@ -216,8 +189,7 @@ We will group `upvote` action and `reply` action into a single category: `EXAMPL ```javascript let exampleCategory = new NotificationCategory({ identifier: "EXAMPLE_CATEGORY", - actions: [upvoteAction, replyAction], - context: "default" + actions: [upvoteAction, replyAction] }); ``` @@ -234,8 +206,8 @@ Notification payload should look like this: ```javascript { aps: { - // ... (alert, sound, badge, etc) - category: "EXAMPLE_CATEGORY" + // ... (alert, sound, badge, etc) + category: "EXAMPLE_CATEGORY" } } ``` @@ -249,9 +221,7 @@ The [example app](https://github.com/wix/react-native-notifications/tree/master/ - `activationMode` - Indicating whether the app should activate to the foreground or background. - `foreground` (default) - Activate the app and put it in the foreground. - `background` - Activate the app and put it in the background. If the app is already in the foreground, it remains in the foreground. -- `behavior` - Indicating additional behavior that the action supports. - - `default` - No additional behavior. - - `textInput` - When button is tapped, the action opens a text input. the text will be delivered to your action callback. +- `textInput` - `TextInput` payload, when supplied, the system will present text input in this action. - `destructive` - A Boolean value indicating whether the action is destructive. When the value of this property is `true`, the system displays the corresponding button differently to indicate that the action is destructive. - `authenticationRequired` - A Boolean value indicating whether the user must unlock the device before the action is performed. @@ -259,9 +229,11 @@ The [example app](https://github.com/wix/react-native-notifications/tree/master/ - `identifier` - The name of the action group (must be unique). - `actions` - An array of `NotificationAction` objects, which related to this category. -- `context` - Indicating the amount of space available for displaying actions in a notification. - - `default` (default) - Displayes up to 4 actions (full UI). - - `minimal` - Displays up tp 2 actions (minimal UI). + +### `TextInput` Payload + +- `buttonTitle` - Title of the `send` button. +- `placeholder` - Placeholder for the `textInput`. #### Get and set application icon badges count (iOS only) diff --git a/docs/notificationsEvents.md b/docs/notificationsEvents.md index 1a1c0b9..124e76c 100644 --- a/docs/notificationsEvents.md +++ b/docs/notificationsEvents.md @@ -6,7 +6,6 @@ When a push notification is received by the device, the application can be in one of the following states: 1. **Forground:** When the app is running and is used by the user right now; in this case, a `notificationReceivedForeground` event will be fired. -2. **Background:** When the app is running in a background state; in this case, a `notificationReceivedBackground` event will be fired. Finally, when a notification is _opened_ by the device user (i.e. tapped-on), a `notificationOpened` event is fired. diff --git a/example/index.ios.js b/example/index.ios.js index b622618..1a251cf 100644 --- a/example/index.ios.js +++ b/example/index.ios.js @@ -18,7 +18,6 @@ let upvoteAction = new NotificationAction({ let replyAction = new NotificationAction({ activationMode: 'background', title: 'Reply', - behavior: 'textInput', authenticationRequired: true, textInput: { buttonTitle: 'Reply now', @@ -45,6 +44,7 @@ class NotificationsExampleApp extends Component { NotificationsIOS.addEventListener('notificationReceivedForeground', this.onNotificationReceivedForeground.bind(this)); NotificationsIOS.addEventListener('notificationOpened', this.onNotificationOpened.bind(this)); + NotificationsIOS.addEventListener('pushKitNotificationReceived', this.onPushKitNotificationReceived.bind(this)); } onPushRegistered(deviceToken) { @@ -59,6 +59,10 @@ class NotificationsExampleApp extends Component { console.log('PushKit Token Received: ' + deviceToken); } + onPushKitNotificationReceived(notification) { + console.log('PushKit notification Received: ' + JSON.stringify(notification)); + } + onNotificationReceivedForeground(notification, completion) { console.log('Notification Received Foreground: ' + JSON.stringify(notification)); this.setState({ @@ -98,8 +102,7 @@ class NotificationsExampleApp extends Component { requestPermissions() { let cat = new NotificationCategory({ identifier: 'SOME_CATEGORY', - actions: [upvoteAction, replyAction], - context: 'default' + actions: [upvoteAction, replyAction] }); NotificationsIOS.requestPermissions([cat]); } diff --git a/example/ios/NotificationsExampleApp/AppDelegate.m b/example/ios/NotificationsExampleApp/AppDelegate.m index be2acd1..5e70937 100644 --- a/example/ios/NotificationsExampleApp/AppDelegate.m +++ b/example/ios/NotificationsExampleApp/AppDelegate.m @@ -25,22 +25,17 @@ self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; - [[RNNotifications sharedInstance] initialize]; + [RNNotifications startMonitorNotifications]; return YES; } -// Required to register for notifications -- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { -// [[RNNotifications sharedInstance] didRegisterUserNotificationSettings:notificationSettings]; -} - - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { - [[RNNotifications sharedInstance] didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; + [RNNotifications didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { - [[RNNotifications sharedInstance] didFailToRegisterForRemoteNotificationsWithError:error]; + [RNNotifications didFailToRegisterForRemoteNotificationsWithError:error]; } @end diff --git a/lib/src/index.ios.js b/lib/src/index.ios.js index a5f1e59..d9b80a7 100644 --- a/lib/src/index.ios.js +++ b/lib/src/index.ios.js @@ -13,13 +13,16 @@ export const DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT = 'remoteNoti export const DEVICE_PUSH_KIT_REGISTERED_EVENT = 'pushKitRegistered'; export const DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT = 'notificationReceivedForeground'; export const DEVICE_NOTIFICATION_OPENED_EVENT = 'notificationOpened'; +export const DEVICE_PUSH_KIT_NOTIFICATION_RECEIVED_EVENT = 'pushKitNotificationReceived'; + const _exportedEvents = [ DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT, DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT, DEVICE_PUSH_KIT_REGISTERED_EVENT, DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT, - DEVICE_NOTIFICATION_OPENED_EVENT + DEVICE_NOTIFICATION_OPENED_EVENT, + DEVICE_PUSH_KIT_NOTIFICATION_RECEIVED_EVENT ]; const _notificationHandlers = new Map(); const _actionHandlers = new Map(); @@ -50,6 +53,7 @@ export default class NotificationsIOS { * - `remoteNotificationsRegistered` : Fired when the user registers for remote notifications. The handler will be invoked with a hex string representing the deviceToken. * - `notificationReceivedForeground` : Fired when a notification (local / remote) is received when app is on foreground state. * - `notificationOpened`: Fired when a notification (local / remote) is opened. + * - `pushKitNotificationReceived` : Fired when a pushKit notification received when app is both on foreground and background state. */ static addEventListener(type: string, handler: Function) { if (_exportedEvents.indexOf(type) !== -1) { @@ -84,6 +88,11 @@ export default class NotificationsIOS { NativeRNNotifications.finishHandlingAction(identifier); }, action) ); + } else if (type === DEVICE_PUSH_KIT_NOTIFICATION_RECEIVED_EVENT) { + listener = DeviceEventEmitter.addListener( + type, + (payload) => handler(new IOSNotification(payload)) + ); } _notificationHandlers.set(handler, listener); diff --git a/lib/src/notification.ios.js b/lib/src/notification.ios.js index 5f611ee..f8d0da8 100644 --- a/lib/src/notification.ios.js +++ b/lib/src/notification.ios.js @@ -10,26 +10,26 @@ export default class IOSNotification { constructor(notification: Object) { this._data = {}; - if (notification.userInfo.aps && - notification.userInfo.aps['content-available'] && - notification.userInfo.aps['content-available'] === 1 && - !notification.userInfo.aps.alert && - !notification.userInfo.aps.sound && + if (notification.aps && + notification.aps['content-available'] && + notification.aps['content-available'] === 1 && + !notification.aps.alert && + !notification.aps.sound && notification.managedAps) { // managed notification this._alert = notification.managedAps.alert; this._sound = notification.managedAps.sound; - this._badge = notification.userInfo.aps.badge; + this._badge = notification.aps.badge; this._category = notification.managedAps.category; this._type = 'managed'; - this._thread = notification.userInfo.aps['thread-id']; + this._thread = notification.aps['thread-id']; } else if ( - notification.userInfo.aps && - notification.userInfo.aps.alert) { + notification.aps && + notification.aps.alert) { // regular notification - this._alert = notification.userInfo.aps.alert; - this._sound = notification.userInfo.aps.sound; - this._badge = notification.userInfo.aps.badge; + this._alert = notification.aps.alert; + this._sound = notification.aps.sound; + this._badge = notification.aps.badge; this._category = notification.category; this._type = 'regular'; this._thread = notification.thread; -- 2.26.2