Commit 448cc12e authored by Lidan Hifi's avatar Lidan Hifi

added permissions handling, added PushKit support for reliable background notifications

parent 6cf68c53
@import UIKit; @import UIKit;
#import "RCTBridgeModule.h" #import "RCTBridgeModule.h"
#import <PushKit/PushKit.h>
@interface RNNotifications : NSObject <RCTBridgeModule> @interface RNNotifications : NSObject <RCTBridgeModule>
+ (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
+ (void)didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings;
+ (void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type;
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification; + (void)didReceiveRemoteNotification:(NSDictionary *)notification;
+ (void)didReceiveLocalNotification:(UILocalNotification *)notification; + (void)didReceiveLocalNotification:(UILocalNotification *)notification;
+ (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler; + (void)handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler;
+ (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler; + (void)handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler;
@end @end
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import <PushKit/PushKit.h>
#import "RCTBridge.h" #import "RCTBridge.h"
#import "RCTEventDispatcher.h" #import "RCTEventDispatcher.h"
#import "RNNotifications.h" #import "RNNotifications.h"
...@@ -10,6 +11,8 @@ ...@@ -10,6 +11,8 @@
NSString* const RNNotificationCreateAction = @"CREATE"; NSString* const RNNotificationCreateAction = @"CREATE";
NSString* const RNNotificationClearAction = @"CLEAR"; NSString* const RNNotificationClearAction = @"CLEAR";
NSString* const RNNotificationsRegistered = @"RNNotificationsRegistered";
NSString* const RNPushKitRegistered = @"RNPushKitRegistered";
NSString* const RNNotificationReceivedForeground = @"RNNotificationReceivedForeground"; NSString* const RNNotificationReceivedForeground = @"RNNotificationReceivedForeground";
NSString* const RNNotificationReceivedBackground = @"RNNotificationReceivedBackground"; NSString* const RNNotificationReceivedBackground = @"RNNotificationReceivedBackground";
NSString* const RNNotificationOpened = @"RNNotificationOpened"; NSString* const RNNotificationOpened = @"RNNotificationOpened";
...@@ -92,6 +95,16 @@ RCT_EXPORT_MODULE() ...@@ -92,6 +95,16 @@ RCT_EXPORT_MODULE()
{ {
_bridge = bridge; _bridge = bridge;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleNotificationsRegistered:)
name:RNNotificationsRegistered
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handlePushKitRegistered:)
name:RNPushKitRegistered
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleNotificationReceivedForeground:) selector:@selector(handleNotificationReceivedForeground:)
name:RNNotificationReceivedForeground name:RNNotificationReceivedForeground
...@@ -111,7 +124,7 @@ RCT_EXPORT_MODULE() ...@@ -111,7 +124,7 @@ RCT_EXPORT_MODULE()
selector:@selector(handleNotificationActionTriggered:) selector:@selector(handleNotificationActionTriggered:)
name:RNNotificationActionTriggered name:RNNotificationActionTriggered
object:nil]; object:nil];
NSDictionary* lastActionInfo = [RNNotificationsBridgeQueue sharedInstance].lastAction; NSDictionary* lastActionInfo = [RNNotificationsBridgeQueue sharedInstance].lastAction;
if (lastActionInfo) { if (lastActionInfo) {
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationActionTriggered [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationActionTriggered
...@@ -119,12 +132,26 @@ RCT_EXPORT_MODULE() ...@@ -119,12 +132,26 @@ RCT_EXPORT_MODULE()
userInfo:lastActionInfo]; userInfo:lastActionInfo];
[RNNotificationsBridgeQueue sharedInstance].lastAction = nil; [RNNotificationsBridgeQueue sharedInstance].lastAction = nil;
} }
} }
/* /*
* Public Methods * Public Methods
*/ */
+ (void)didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
if ([UIApplication instancesRespondToSelector:@selector(registerForRemoteNotifications)]) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}
+ (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationsRegistered
object:self
userInfo:@{@"deviceToken": [self deviceTokenToString:deviceToken]}];
}
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification + (void)didReceiveRemoteNotification:(NSDictionary *)notification
{ {
UIApplicationState state = [UIApplication sharedApplication].applicationState; UIApplicationState state = [UIApplication sharedApplication].applicationState;
...@@ -154,12 +181,12 @@ RCT_EXPORT_MODULE() ...@@ -154,12 +181,12 @@ RCT_EXPORT_MODULE()
} }
} }
+ (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler + (void)handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler
{ {
[self emitNotificationActionForIdentifier:identifier responseInfo:responseInfo userInfo:notification.userInfo completionHandler:completionHandler]; [self emitNotificationActionForIdentifier:identifier responseInfo:responseInfo userInfo:notification.userInfo completionHandler:completionHandler];
} }
+ (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler + (void)handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler
{ {
[self emitNotificationActionForIdentifier:identifier responseInfo:responseInfo userInfo:userInfo completionHandler:completionHandler]; [self emitNotificationActionForIdentifier:identifier responseInfo:responseInfo userInfo:userInfo completionHandler:completionHandler];
} }
...@@ -261,7 +288,19 @@ RCT_EXPORT_MODULE() ...@@ -261,7 +288,19 @@ RCT_EXPORT_MODULE()
return [NSString stringWithFormat:@"%@.%@", [[NSBundle mainBundle] bundleIdentifier], notificationId]; return [NSString stringWithFormat:@"%@.%@", [[NSBundle mainBundle] bundleIdentifier], notificationId];
} }
+ (void)updateNotificationCategories:(NSArray *)json + (NSString *)deviceTokenToString:(NSData *)deviceToken
{
NSMutableString *result = [NSMutableString string];
NSUInteger deviceTokenLength = deviceToken.length;
const unsigned char *bytes = deviceToken.bytes;
for (NSUInteger i = 0; i < deviceTokenLength; i++) {
[result appendFormat:@"%02x", bytes[i]];
}
return [result copy];
}
+ (void)requestPermissionsWithCategories:(NSArray *)json
{ {
NSMutableSet* categories = nil; NSMutableSet* categories = nil;
...@@ -297,14 +336,46 @@ RCT_EXPORT_MODULE() ...@@ -297,14 +336,46 @@ RCT_EXPORT_MODULE()
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationActionTriggered [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationActionTriggered
object:self object:self
userInfo:info]; userInfo:info];
[RNNotificationsBridgeQueue sharedInstance].lastAction = info; [RNNotificationsBridgeQueue sharedInstance].lastAction = info;
[RNNotificationsBridgeQueue sharedInstance].lastCompletionHandler = completionHandler; [RNNotificationsBridgeQueue sharedInstance].lastCompletionHandler = completionHandler;
} }
+ (void)registerPushKit
{
// Create a push registry object
PKPushRegistry* pushKitRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
// Set the registry delegate to app delegate
pushKitRegistry.delegate = [[UIApplication sharedApplication] delegate];
pushKitRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}
+ (void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type
{
[[NSNotificationCenter defaultCenter] postNotificationName:RNPushKitRegistered
object:self
userInfo:@{@"pushKitToken": [self deviceTokenToString:credentials.token]}];
}
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
{
[RNNotifications didReceiveRemoteNotification:payload.dictionaryPayload];
}
/* /*
* Javascript events * Javascript events
*/ */
- (void)handleNotificationsRegistered:(NSNotification *)notification
{
[_bridge.eventDispatcher sendDeviceEventWithName:@"remoteNotificationsRegistered" body:notification.userInfo];
}
- (void)handlePushKitRegistered:(NSNotification *)notification
{
[_bridge.eventDispatcher sendDeviceEventWithName:@"pushKitRegistered" body:notification.userInfo];
}
- (void)handleNotificationReceivedForeground:(NSNotification *)notification - (void)handleNotificationReceivedForeground:(NSNotification *)notification
{ {
[_bridge.eventDispatcher sendDeviceEventWithName:@"notificationReceivedForeground" body:notification.userInfo]; [_bridge.eventDispatcher sendDeviceEventWithName:@"notificationReceivedForeground" body:notification.userInfo];
...@@ -328,9 +399,9 @@ RCT_EXPORT_MODULE() ...@@ -328,9 +399,9 @@ RCT_EXPORT_MODULE()
/* /*
* React Native exported methods * React Native exported methods
*/ */
RCT_EXPORT_METHOD(updateNotificationCategories:(NSArray *)json) RCT_EXPORT_METHOD(requestPermissionsWithCategories:(NSArray *)json)
{ {
[RNNotifications updateNotificationCategories:json]; [RNNotifications requestPermissionsWithCategories:json];
} }
RCT_EXPORT_METHOD(log:(NSString *)message) RCT_EXPORT_METHOD(log:(NSString *)message)
...@@ -347,4 +418,20 @@ RCT_EXPORT_METHOD(completionHandler) ...@@ -347,4 +418,20 @@ RCT_EXPORT_METHOD(completionHandler)
} }
} }
RCT_EXPORT_METHOD(abandonPermissions)
{
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
}
RCT_EXPORT_METHOD(registerPushKit)
{
[RNNotifications registerPushKit];
}
RCT_EXPORT_METHOD(backgroundTimeRemaining:(RCTResponseSenderBlock)callback)
{
NSTimeInterval remainingTime = [UIApplication sharedApplication].backgroundTimeRemaining;
callback(@[ [NSNumber numberWithDouble:remainingTime] ]);
}
@end @end
...@@ -8,8 +8,7 @@ import React, { ...@@ -8,8 +8,7 @@ import React, {
Component, Component,
StyleSheet, StyleSheet,
Text, Text,
View, View
PushNotificationIOS
} from 'react-native'; } from 'react-native';
import NotificationsIOS, { NotificationAction, NotificationCategory } from 'react-native-notifications'; import NotificationsIOS, { NotificationAction, NotificationCategory } from 'react-native-notifications';
...@@ -44,33 +43,38 @@ let cat = new NotificationCategory({ ...@@ -44,33 +43,38 @@ let cat = new NotificationCategory({
context: "default" context: "default"
}); });
NotificationsIOS.setCategories([cat]);
class NotificationsExampleApp extends Component { class NotificationsExampleApp extends Component {
constructor() { constructor() {
super(); super();
PushNotificationIOS.addEventListener('register', this.onPushRegistered.bind(this)); NotificationsIOS.addEventListener('remoteNotificationsRegistered', this.onPushRegistered.bind(this));
NotificationsIOS.requestPermissions([cat]);
NotificationsIOS.addEventListener('pushKitRegistered', this.onPushKitRegistered.bind(this));
NotificationsIOS.registerPushKit([cat]);
NotificationsIOS.addEventListener('notificationReceivedForeground', this.onNotificationReceivedForeground.bind(this)); NotificationsIOS.addEventListener('notificationReceivedForeground', this.onNotificationReceivedForeground.bind(this));
NotificationsIOS.addEventListener('notificationReceivedBackground', this.onNotificationReceivedBackground.bind(this)); NotificationsIOS.addEventListener('notificationReceivedBackground', this.onNotificationReceivedBackground.bind(this));
NotificationsIOS.addEventListener('notificationOpened', this.onNotificationOpened.bind(this)); NotificationsIOS.addEventListener('notificationOpened', this.onNotificationOpened.bind(this));
} }
componentDidMount() {
// PushNotificationIOS.requestPermissions();
}
onPushRegistered(deviceToken) { onPushRegistered(deviceToken) {
console.log("Device Token Received: " + deviceToken); console.log("Device Token Received: " + deviceToken);
} }
onPushKitRegistered(deviceToken) {
console.log("PushKit Token Received: " + deviceToken);
}
onNotificationReceivedForeground(notification) { onNotificationReceivedForeground(notification) {
console.log("Notification Received Foreground: " + JSON.stringify(notification)); console.log("Notification Received Foreground: " + JSON.stringify(notification));
} }
onNotificationReceivedBackground(notification) { onNotificationReceivedBackground(notification) {
console.log("Notification Received Background: " + JSON.stringify(notification)); NotificationsIOS.log("Notification Received Background: " + JSON.stringify(notification));
NotificationsIOS.backgroundTimeRemaining(time => NotificationsIOS.log("remaining background time: " + time));
} }
onNotificationOpened(notification) { onNotificationOpened(notification) {
...@@ -98,6 +102,8 @@ class NotificationsExampleApp extends Component { ...@@ -98,6 +102,8 @@ class NotificationsExampleApp extends Component {
NotificationsIOS.removeEventListener('notificationReceivedForeground', this.onNotificationReceivedForeground.bind(this)); NotificationsIOS.removeEventListener('notificationReceivedForeground', this.onNotificationReceivedForeground.bind(this));
NotificationsIOS.removeEventListener('notificationReceivedBackground', this.onNotificationReceivedBackground.bind(this)); NotificationsIOS.removeEventListener('notificationReceivedBackground', this.onNotificationReceivedBackground.bind(this));
NotificationsIOS.removeEventListener('notificationOpened', this.onNotificationOpened.bind(this)); NotificationsIOS.removeEventListener('notificationOpened', this.onNotificationOpened.bind(this));
NotificationsIOS.removeEventListener('remoteNotificationsRegistered', this.onPushRegistered.bind(this));
NotificationsIOS.removeEventListener('pushKitRegistered', this.onPushKitRegistered.bind(this));
// NotificationsIOS.resetCategories(); // NotificationsIOS.resetCategories();
} }
......
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate> #import <PushKit/PushKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, PKPushRegistryDelegate>
@property (nonatomic, strong) UIWindow *window; @property (nonatomic, strong) UIWindow *window;
......
...@@ -8,10 +8,11 @@ ...@@ -8,10 +8,11 @@
*/ */
#import "AppDelegate.h" #import "AppDelegate.h"
#import "RCTPushNotificationManager.h"
#import "RCTRootView.h" #import "RCTRootView.h"
#import "RNNotifications.h" #import "RNNotifications.h"
#import <PushKit/PushKit.h>
@implementation AppDelegate @implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
...@@ -32,7 +33,7 @@ ...@@ -32,7 +33,7 @@
* on the same Wi-Fi network. * on the same Wi-Fi network.
*/ */
jsCodeLocation = [NSURL URLWithString:@"http://192.168.1.15:8081/index.ios.bundle?platform=ios&dev=true"]; jsCodeLocation = [NSURL URLWithString:@"http://172.31.8.67:8081/index.ios.bundle?platform=ios&dev=true"];
/** /**
* OPTION 2 * OPTION 2
...@@ -54,26 +55,37 @@ ...@@ -54,26 +55,37 @@
rootViewController.view = rootView; rootViewController.view = rootView;
self.window.rootViewController = rootViewController; self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible]; [self.window makeKeyAndVisible];
return YES; return YES;
} }
// PushKit API Example
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type
{
[RNNotifications didUpdatePushCredentials:credentials forType:type];
}
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
{
[RNNotifications didReceiveRemoteNotification:payload.dictionaryPayload];
}
// Required to register for notifications // Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{ {
[RCTPushNotificationManager didRegisterUserNotificationSettings:notificationSettings]; [RNNotifications didRegisterUserNotificationSettings:notificationSettings];
} }
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{ {
[RCTPushNotificationManager didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; [RNNotifications didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
} }
// Required for the notification event. // Required for the notification event.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification {
{
[RNNotifications didReceiveRemoteNotification:notification]; [RNNotifications didReceiveRemoteNotification:notification];
} }
...@@ -87,12 +99,12 @@ ...@@ -87,12 +99,12 @@
// Required for the notification actions. // Required for the notification actions.
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler - (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler
{ {
[RNNotifications application:application handleActionWithIdentifier:identifier forLocalNotification:notification withResponseInfo:responseInfo completionHandler: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 - (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler
{ {
[RNNotifications application:application handleActionWithIdentifier:identifier forRemoteNotification:userInfo withResponseInfo:responseInfo completionHandler:completionHandler]; [RNNotifications handleActionWithIdentifier:identifier forRemoteNotification:userInfo withResponseInfo:responseInfo completionHandler:completionHandler];
} }
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
<key>UIBackgroundModes</key> <key>UIBackgroundModes</key>
<array> <array>
<string>remote-notification</string> <string>remote-notification</string>
<string>voip</string>
</array> </array>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>
<string>LaunchScreen</string> <string>LaunchScreen</string>
......
...@@ -8,11 +8,21 @@ import Map from "core-js/library/es6/map"; ...@@ -8,11 +8,21 @@ import Map from "core-js/library/es6/map";
const NativeRNNotifications = NativeModules.RNNotifications; // eslint-disable-line no-unused-vars const NativeRNNotifications = NativeModules.RNNotifications; // eslint-disable-line no-unused-vars
import IOSNotification from "./notification.ios"; import IOSNotification from "./notification.ios";
export const DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT = "remoteNotificationsRegistered";
export const DEVICE_PUSH_KIT_REGISTERED_EVENT = "pushKitRegistered";
export const DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT = "notificationReceivedForeground"; export const DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT = "notificationReceivedForeground";
export const DEVICE_NOTIFICATION_RECEIVED_BACKGROUND_EVENT = "notificationReceivedBackground"; export const DEVICE_NOTIFICATION_RECEIVED_BACKGROUND_EVENT = "notificationReceivedBackground";
export const DEVICE_NOTIFICATION_OPENED_EVENT = "notificationOpened"; export const DEVICE_NOTIFICATION_OPENED_EVENT = "notificationOpened";
export const DEVICE_NOTIFICATION_ACTION_RECEIVED = "notificationActionReceived";
const DEVICE_NOTIFICATION_ACTION_RECEIVED = "notificationActionReceived";
const _exportedEvents = [
DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT,
DEVICE_PUSH_KIT_REGISTERED_EVENT,
DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT,
DEVICE_NOTIFICATION_RECEIVED_BACKGROUND_EVENT,
DEVICE_NOTIFICATION_OPENED_EVENT
];
let _notificationHandlers = new Map(); let _notificationHandlers = new Map();
let _actionHandlers = new Map(); let _actionHandlers = new Map();
let _actionListener; let _actionListener;
...@@ -37,18 +47,31 @@ export default class NotificationsIOS { ...@@ -37,18 +47,31 @@ export default class NotificationsIOS {
* *
* Valid events are: * Valid events are:
* *
* - `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. * - `notificationReceivedForeground` : Fired when a notification (local / remote) is received when app is on foreground state.
* - `notificationReceivedBackground`: Fired when a background notification is received. * - `notificationReceivedBackground`: Fired when a background notification is received.
* - `notificationOpened`: Fired when a notification (local / remote) is opened. * - `notificationOpened`: Fired when a notification (local / remote) is opened.
*/ */
static addEventListener(type: string, handler: Function) { static addEventListener(type: string, handler: Function) {
if (type === DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT || if (_exportedEvents.indexOf(type) !== -1) {
type === DEVICE_NOTIFICATION_RECEIVED_BACKGROUND_EVENT || let listener;
type === DEVICE_NOTIFICATION_OPENED_EVENT) {
let listener = DeviceEventEmitter.addListener( if (type === DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT) {
type, listener = DeviceEventEmitter.addListener(
notification => handler(new IOSNotification(notification)) DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT,
); registration => handler(registration.deviceToken)
);
} else if (type === DEVICE_PUSH_KIT_REGISTERED_EVENT) {
listener = DeviceEventEmitter.addListener(
DEVICE_PUSH_KIT_REGISTERED_EVENT,
registration => handler(registration.pushKitToken)
);
} else {
listener = DeviceEventEmitter.addListener(
type,
notification => handler(new IOSNotification(notification))
);
}
_notificationHandlers.set(handler, listener); _notificationHandlers.set(handler, listener);
} }
...@@ -59,9 +82,7 @@ export default class NotificationsIOS { ...@@ -59,9 +82,7 @@ export default class NotificationsIOS {
* memory leaks * memory leaks
*/ */
static removeEventListener(type: string, handler: Function) { static removeEventListener(type: string, handler: Function) {
if (type === DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT || if (_exportedEvents.indexOf(type) !== -1) {
type === DEVICE_NOTIFICATION_RECEIVED_BACKGROUND_EVENT ||
type === DEVICE_NOTIFICATION_OPENED_EVENT) {
let listener = _notificationHandlers.get(handler); let listener = _notificationHandlers.get(handler);
if (!listener) { if (!listener) {
return; return;
...@@ -85,8 +106,7 @@ export default class NotificationsIOS { ...@@ -85,8 +106,7 @@ export default class NotificationsIOS {
/** /**
* Sets the notification categories * Sets the notification categories
*/ */
/* eslint-disable no-unused-vars */ static requestPermissions(categories: Array<NotificationCategory>) {
static setCategories(categories: Array<NotificationCategory>) {
let notificationCategories = []; let notificationCategories = [];
if (categories) { if (categories) {
...@@ -105,7 +125,14 @@ export default class NotificationsIOS { ...@@ -105,7 +125,14 @@ export default class NotificationsIOS {
}); });
} }
NativeRNNotifications.updateNotificationCategories(notificationCategories); NativeRNNotifications.requestPermissionsWithCategories(notificationCategories);
}
/**
* Unregister for all remote notifications received via Apple Push Notification service.
*/
static abandonPermissions() {
NativeRNNotifications.abandonPermissions();
} }
/** /**
...@@ -120,6 +147,14 @@ export default class NotificationsIOS { ...@@ -120,6 +147,14 @@ export default class NotificationsIOS {
_actionHandlers.clear(); _actionHandlers.clear();
} }
static registerPushKit() {
NativeRNNotifications.registerPushKit();
}
static backgroundTimeRemaining(callback: Function) {
NativeRNNotifications.backgroundTimeRemaining(callback);
}
static log(message) { static log(message) {
NativeRNNotifications.log(message); NativeRNNotifications.log(message);
} }
......
...@@ -7,27 +7,44 @@ import sinon from "sinon"; ...@@ -7,27 +7,44 @@ import sinon from "sinon";
describe("NotificationsIOS", () => { describe("NotificationsIOS", () => {
let deviceEvents = [ let deviceEvents = [
"pushKitRegistered",
"remoteNotificationsRegistered",
"notificationReceivedForeground", "notificationReceivedForeground",
"notificationReceivedBackground", "notificationReceivedBackground",
"notificationOpened" "notificationOpened"
]; ];
let deviceAddEventListener, deviceRemoveEventListener, nativeAppAddEventListener, nativeAppRemoveEventListener, nativeUpdateNotificationCategories; /*eslint-disable indent*/
let deviceAddEventListener,
deviceRemoveEventListener,
nativeAppAddEventListener,
nativeAppRemoveEventListener,
nativeRequestPermissionsWithCategories,
nativeAbandonPermissions,
nativeRegisterPushKit,
nativeBackgroundTimeRemaining;
let NotificationsIOS, NotificationAction, NotificationCategory; let NotificationsIOS, NotificationAction, NotificationCategory;
let someHandler = () => {}; let someHandler = () => {};
/*eslint-enable indent*/
before(() => { before(() => {
deviceAddEventListener = sinon.spy(); deviceAddEventListener = sinon.spy();
deviceRemoveEventListener = sinon.spy(); deviceRemoveEventListener = sinon.spy();
nativeAppAddEventListener = sinon.spy(); nativeAppAddEventListener = sinon.spy();
nativeAppRemoveEventListener = sinon.spy(); nativeAppRemoveEventListener = sinon.spy();
nativeUpdateNotificationCategories = sinon.spy(); nativeRequestPermissionsWithCategories = sinon.spy();
nativeAbandonPermissions = sinon.spy();
nativeRegisterPushKit = sinon.spy();
nativeBackgroundTimeRemaining = sinon.spy();
let libUnderTest = proxyquire("../index.ios", { let libUnderTest = proxyquire("../index.ios", {
"react-native": { "react-native": {
NativeModules: { NativeModules: {
RNNotifications: { RNNotifications: {
updateNotificationCategories: nativeUpdateNotificationCategories requestPermissionsWithCategories: nativeRequestPermissionsWithCategories,
abandonPermissions: nativeAbandonPermissions,
registerPushKit: nativeRegisterPushKit,
backgroundTimeRemaining: nativeBackgroundTimeRemaining
} }
}, },
NativeAppEventEmitter: { NativeAppEventEmitter: {
...@@ -58,7 +75,10 @@ describe("NotificationsIOS", () => { ...@@ -58,7 +75,10 @@ describe("NotificationsIOS", () => {
deviceRemoveEventListener.reset(); deviceRemoveEventListener.reset();
nativeAppAddEventListener.reset(); nativeAppAddEventListener.reset();
nativeAppRemoveEventListener.reset(); nativeAppRemoveEventListener.reset();
nativeUpdateNotificationCategories.reset(); nativeRequestPermissionsWithCategories.reset();
nativeAbandonPermissions.reset();
nativeRegisterPushKit.reset();
nativeBackgroundTimeRemaining.reset();
}); });
after(() => { after(() => {
...@@ -66,7 +86,10 @@ describe("NotificationsIOS", () => { ...@@ -66,7 +86,10 @@ describe("NotificationsIOS", () => {
deviceRemoveEventListener = null; deviceRemoveEventListener = null;
nativeAppAddEventListener = null; nativeAppAddEventListener = null;
nativeAppRemoveEventListener = null; nativeAppRemoveEventListener = null;
nativeUpdateNotificationCategories = null; nativeRequestPermissionsWithCategories = null;
nativeAbandonPermissions = null;
nativeRegisterPushKit = null;
nativeBackgroundTimeRemaining = null;
NotificationsIOS = null; NotificationsIOS = null;
NotificationAction = null; NotificationAction = null;
...@@ -128,25 +151,25 @@ describe("NotificationsIOS", () => { ...@@ -128,25 +151,25 @@ describe("NotificationsIOS", () => {
}); });
}); });
describe("register categories", () => { describe("register push notifications", () => {
it("should call native update categories with array of categories", () => { it("should call native request permissions with array of categories", () => {
NotificationsIOS.setCategories([someCategory]); NotificationsIOS.requestPermissions([someCategory]);
expect(nativeUpdateNotificationCategories).to.have.been.calledWith([{ expect(nativeRequestPermissionsWithCategories).to.have.been.calledWith([{
identifier: "SOME_CATEGORY", identifier: "SOME_CATEGORY",
actions: [actionOpts], actions: [actionOpts],
context: "default" context: "default"
}]); }]);
}); });
it("should call native update categories with empty array if no categories specified", () => { it("should call native request permissions with empty array if no categories specified", () => {
NotificationsIOS.setCategories(); NotificationsIOS.requestPermissions();
expect(nativeUpdateNotificationCategories).to.have.been.calledWith([]); expect(nativeRequestPermissionsWithCategories).to.have.been.calledWith([]);
}); });
it("should subscribe to 'notificationActionReceived' event once, with a single event handler", () => { it("should subscribe to 'notificationActionReceived' event once, with a single event handler", () => {
NotificationsIOS.setCategories([someCategory]); NotificationsIOS.requestPermissions([someCategory]);
expect(nativeAppAddEventListener).to.have.been.calledOnce; expect(nativeAppAddEventListener).to.have.been.calledOnce;
expect(nativeAppAddEventListener).to.have.been.calledWith("notificationActionReceived", sinon.match.func); expect(nativeAppAddEventListener).to.have.been.calledWith("notificationActionReceived", sinon.match.func);
...@@ -154,11 +177,35 @@ describe("NotificationsIOS", () => { ...@@ -154,11 +177,35 @@ describe("NotificationsIOS", () => {
}); });
describe("reset categories", () => { describe("reset categories", () => {
it("should remove 'notificationActionReceived' event handler", function () { it("should remove 'notificationActionReceived' event handler", () => {
NotificationsIOS.resetCategories(); NotificationsIOS.resetCategories();
expect(nativeAppRemoveEventListener).to.have.been.calledOnce; expect(nativeAppRemoveEventListener).to.have.been.calledOnce;
}); });
}); });
}); });
describe("register push kit for background notifications", function () {
it("should call native register push kit method", function () {
NotificationsIOS.registerPushKit();
expect(nativeRegisterPushKit).to.have.been.called;
});
});
describe("Abandon push notifications permissions", () => {
it("should call native abandon permissions method", () => {
NotificationsIOS.abandonPermissions();
expect(nativeAbandonPermissions).to.have.been.called;
});
});
describe("Get background remaining time", () => {
it("should call native background remaining time method", () => {
NotificationsIOS.backgroundTimeRemaining(time => { });
expect(nativeBackgroundTimeRemaining).to.have.been.called;
});
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment