diff --git a/RNNotifications/RNNRouter.h b/RNNotifications/RNNRouter.h deleted file mode 100644 index 049280f843530c7d512d62028db3104db0731c5f..0000000000000000000000000000000000000000 --- a/RNNotifications/RNNRouter.h +++ /dev/null @@ -1,40 +0,0 @@ -// -// NRNNManager.h -// NRNNOtifications -// -// Created by Muhammad Abed El Razek on 09/01/2019. -// Copyright © 2019 Wix. All rights reserved. -// -#import -#import -#import -#import - - -@protocol RNNRerouterDelegate -- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken; -- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error; -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler; -- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler; -- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler; -- (void)handlePushKitRegistered:(NSDictionary *)notification; - -@end - -@interface RNNRouter : NSObject - -+ (nonnull instancetype)sharedInstance; - -@property (nonatomic, weak) id _Nullable delegate; - -- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken; -- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error; -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(nullable void (^)(UIBackgroundFetchResult))completionHandler; -- (void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type; -- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type; -- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler; -- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler; - - - -@end diff --git a/RNNotifications/RNNRouter.m b/RNNotifications/RNNRouter.m deleted file mode 100644 index 57bfece38f020bc38c87abaef4a2f867456bbc87..0000000000000000000000000000000000000000 --- a/RNNotifications/RNNRouter.m +++ /dev/null @@ -1,149 +0,0 @@ -// -// NRNNManager.m -// NRNNOtifications -// -// Created by Muhammad Abed El Razek on 09/01/2019. -// Copyright © 2019 Wix. All rights reserved. -// - -#import "RNNRouter.h" -#import "RNNotifications.h" -//RNNNotifications's router (delegater) ::: singleton which routes all the static, system functions delegate calls to RNNNotifications insatnce ; can't have and RNNNotifications instance from outside of it's class - - - - -@interface RNNRouter() - -@property(nonatomic,strong) NSMutableArray* pendingDelegateCalls; - -@end - -@implementation RNNRouter - -+ (nonnull instancetype)sharedInstance -{ - static RNNRouter* sharedInstance = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedInstance = [self new]; - }); - return sharedInstance; -} - - - -- (instancetype)init -{ - self = [super init]; - if(self) - { - _pendingDelegateCalls = [NSMutableArray new]; - - } - return self; -} - - -- (void)setDelegate:(id)delegate -{ - _delegate = delegate; - - while (self.pendingDelegateCalls.count > 0) - { - void(^block)(void) = _pendingDelegateCalls.lastObject; - block(); - [_pendingDelegateCalls removeLastObject]; - } - - -} - - -/* - ______ ______ _ _ - | ___ \ | ___ \ | | (_) - | |_/ /___ ______| |_/ /___ _ _| |_ _ _ __ __ _ - | // _ \______| // _ \| | | | __| | '_ \ / _` | - | |\ \ __/ | |\ \ (_) | |_| | |_| | | | | (_| | - \_| \_\___| \_| \_\___/ \__,_|\__|_|_| |_|\__, | - __/ | - |___/ - */ -///////////////////////////////////////////////////////////////// -#pragma mark static calls for RNNNotifications rerouting purpous functions -//////////////////////////////////////////////////////////////// -- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler -{ - void(^callLaterBlock)(void) = ^{ - [self->_delegate userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler]; - }; - - if(_delegate) - { - callLaterBlock(); - } - else // //called and _delegate is not set yet, need to store to call later - { - [_pendingDelegateCalls insertObject:callLaterBlock atIndex:0]; - } -} - -- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler -{ - void(^callLaterBlock)(void) = ^{ - [self->_delegate userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler]; - }; - - if(_delegate) - { - callLaterBlock(); - } - else //called and _delegate is not set yet, need to store to call later - { - [_pendingDelegateCalls insertObject:callLaterBlock atIndex:0]; - } -} - -- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken -{ - if (self.delegate != nil) - { - [self.delegate application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; - } -} - -- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error -{ - if (self.delegate != nil) - { - [self.delegate application:application didFailToRegisterForRemoteNotificationsWithError:error]; - } -} - -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler -{ - if (self.delegate != nil) - { - [self.delegate application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; - } -} - - -- (void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type -{ - if(self.delegate != nil) - { - [self.delegate handlePushKitRegistered:@{@"pushKitToken": [RNNotifications deviceTokenToString:credentials.token]}]; - } -} - -- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type -{ - if (self.delegate != nil) - { - [self.delegate application:nil didReceiveRemoteNotification:payload.dictionaryPayload fetchCompletionHandler:nil]; - } -} - -@end diff --git a/RNNotifications/RNNotifications.h b/RNNotifications/RNNotifications.h index 3c6dbb03adc099e9cd978ad2d0ab52a64e0cb705..b1c34de28bfc3c481d70fff12c09491ed8f53975 100644 --- a/RNNotifications/RNNotifications.h +++ b/RNNotifications/RNNotifications.h @@ -2,10 +2,18 @@ #import #import -#import "RNNRouter.h" -#import +@interface RNNotifications : NSObject + ++ (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken; ++ (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error; ++ (void)didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings; ++ (void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type; + ++ (void)didReceiveRemoteNotification:(NSDictionary *)notification; ++ (void)didReceiveLocalNotification:(UILocalNotification *)notification; + ++ (void)handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler; ++ (void)handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler; -@interface RNNotifications : RCTEventEmitter -+ (NSString *)deviceTokenToString:(NSData *)deviceToken; @end diff --git a/RNNotifications/RNNotifications.m b/RNNotifications/RNNotifications.m index cafa406e9dd54c05a5bbc9ea827c03cdaec72174..bebbf9a556a2b2af223af3e37b5cec8dbc88d685 100644 --- a/RNNotifications/RNNotifications.m +++ b/RNNotifications/RNNotifications.m @@ -1,5 +1,6 @@ #import +#import #import #import #import "RNNotifications.h" @@ -13,51 +14,94 @@ NSString* const RNNotificationCreateAction = @"CREATE"; NSString* const RNNotificationClearAction = @"CLEAR"; -NSString* const RNNotificationsRegistered = @"remoteNotificationsRegistered"; -NSString* const RNNotificationsRegistrationFailed = @"remoteNotificationsRegistrationFailed"; -NSString* const RNPushKitRegistered = @"pushKitRegistered"; -NSString* const RNNotificationReceivedForeground = @"notificationReceivedForeground"; -NSString* const RNNotificationReceivedBackground = @"notificationReceivedBackground"; -NSString* const RNNotificationOpened = @"notificationOpened"; +NSString* const RNNotificationsRegistered = @"RNNotificationsRegistered"; +NSString* const RNNotificationsRegistrationFailed = @"RNNotificationsRegistrationFailed"; +NSString* const RNPushKitRegistered = @"RNPushKitRegistered"; +NSString* const RNNotificationReceivedForeground = @"RNNotificationReceivedForeground"; +NSString* const RNNotificationReceivedBackground = @"RNNotificationReceivedBackground"; +NSString* const RNNotificationOpened = @"RNNotificationOpened"; NSString* const RNNotificationActionTriggered = @"RNNotificationActionTriggered"; -NSString* const RNNotificationActionReceived = @"notificationActionReceived"; -//NSString* const RNNotificationActionDismissed = @"RNNotificationActionDismissed"; +/* + * Converters for Interactive Notifications + */ +@implementation RCTConvert (UIUserNotificationActivationMode) +RCT_ENUM_CONVERTER(UIUserNotificationActivationMode, (@{ + @"foreground": @(UIUserNotificationActivationModeForeground), + @"background": @(UIUserNotificationActivationModeBackground) + }), UIUserNotificationActivationModeForeground, integerValue) +@end -//////////////////////////////////////////////////////////////// -#pragma mark conversions -//////////////////////////////////////////////////////////////// +@implementation RCTConvert (UIUserNotificationActionContext) +RCT_ENUM_CONVERTER(UIUserNotificationActionContext, (@{ + @"default": @(UIUserNotificationActionContextDefault), + @"minimal": @(UIUserNotificationActionContextMinimal) + }), UIUserNotificationActionContextDefault, integerValue) +@end @implementation RCTConvert (UIUserNotificationActionBehavior) -RCT_ENUM_CONVERTER(UNNotificationActionOptions, (@{ - @"authRequired": @(UNNotificationActionOptionAuthenticationRequired), - @"textInput": @(UNNotificationActionOptionDestructive), - @"foreGround": @(UNNotificationActionOptionForeground) - }), UNNotificationActionOptionAuthenticationRequired, integerValue) +/* iOS 9 only */ +RCT_ENUM_CONVERTER(UIUserNotificationActionBehavior, (@{ + @"default": @(UIUserNotificationActionBehaviorDefault), + @"textInput": @(UIUserNotificationActionBehaviorTextInput) + }), UIUserNotificationActionBehaviorDefault, integerValue) @end -@implementation RCTConvert (UNNotificationCategoryOptions) -RCT_ENUM_CONVERTER(UNNotificationCategoryOptions, (@{ - @"none": @(UNNotificationCategoryOptionNone), - @"customDismiss": @(UNNotificationCategoryOptionCustomDismissAction), - @"allowInCarPlay": @(UNNotificationCategoryOptionAllowInCarPlay), - // @"hiddenPreviewsShowTitle": @(UNNotificationCategoryOptionHiddenPreviewsShowTitle), - // @"hiddenPreviewsShowSubtitle": @(UNNotificationCategoryOptionHiddenPreviewsShowSubtitle) - }), UNNotificationCategoryOptionNone, integerValue) +@implementation RCTConvert (UIMutableUserNotificationAction) ++ (UIMutableUserNotificationAction *)UIMutableUserNotificationAction:(id)json +{ + NSDictionary *details = [self NSDictionary:json]; + + UIMutableUserNotificationAction* action =[UIMutableUserNotificationAction new]; + action.activationMode = [RCTConvert UIUserNotificationActivationMode:details[@"activationMode"]]; + action.behavior = [RCTConvert UIUserNotificationActionBehavior:details[@"behavior"]]; + action.authenticationRequired = [RCTConvert BOOL:details[@"authenticationRequired"]]; + action.destructive = [RCTConvert BOOL:details[@"destructive"]]; + action.title = [RCTConvert NSString:details[@"title"]]; + action.identifier = [RCTConvert NSString:details[@"identifier"]]; + + return action; +} @end +@implementation RCTConvert (UIMutableUserNotificationCategory) ++ (UIMutableUserNotificationCategory *)UIMutableUserNotificationCategory:(id)json +{ + NSDictionary *details = [self NSDictionary:json]; + + UIMutableUserNotificationCategory* category = [UIMutableUserNotificationCategory new]; + category.identifier = details[@"identifier"]; + // category actions + NSMutableArray* actions = [NSMutableArray new]; + for (NSDictionary* actionJson in [RCTConvert NSArray:details[@"actions"]]) { + [actions addObject:[RCTConvert UIMutableUserNotificationAction:actionJson]]; + } + [category setActions:actions forContext:[RCTConvert UIUserNotificationActionContext:details[@"context"]]]; -@implementation RCTConvert (UNNotificationAction) -+ (UNNotificationAction*) UNNotificationAction:(id)json + return category; +} +@end + +@implementation RCTConvert (UILocalNotification) ++ (UILocalNotification *)UILocalNotification:(id)json { NSDictionary *details = [self NSDictionary:json]; - UNNotificationAction* action = [UNNotificationAction actionWithIdentifier:details[@"identifier"] - title:details[@"title"] - options:[RCTConvert UNNotificationActionOptions:details[@"options"]]]; - - return action; + + UILocalNotification* notification = [UILocalNotification new]; + notification.fireDate = [RCTConvert NSDate:details[@"fireDate"]]; + notification.alertBody = [RCTConvert NSString:details[@"alertBody"]]; + notification.alertTitle = [RCTConvert NSString:details[@"alertTitle"]]; + notification.alertAction = [RCTConvert NSString:details[@"alertAction"]]; + notification.soundName = [RCTConvert NSString:details[@"soundName"]] ?: UILocalNotificationDefaultSoundName; + if ([RCTConvert BOOL:details[@"silent"]]) { + notification.soundName = nil; + } + notification.userInfo = [RCTConvert NSDictionary:details[@"userInfo"]] ?: @{}; + notification.category = [RCTConvert NSString:details[@"category"]]; + + return notification; } @end @@ -65,22 +109,21 @@ RCT_ENUM_CONVERTER(UNNotificationCategoryOptions, (@{ + (UNNotificationRequest *)UNNotificationRequest:(id)json withId:(NSString*)notificationId { NSDictionary *details = [self NSDictionary:json]; - + UNMutableNotificationContent *content = [UNMutableNotificationContent new]; content.body = [RCTConvert NSString:details[@"alertBody"]]; content.title = [RCTConvert NSString:details[@"alertTitle"]]; - content.sound = [RCTConvert NSString:details[@"soundName"]] ? [UNNotificationSound soundNamed:[RCTConvert NSString:details[@"soundName"]]] : [UNNotificationSound defaultSound]; - if ([RCTConvert BOOL:details[@"silent"]]) - { + content.sound = [RCTConvert NSString:details[@"soundName"]] + ? [UNNotificationSound soundNamed:[RCTConvert NSString:details[@"soundName"]]] + : [UNNotificationSound defaultSound]; + if ([RCTConvert BOOL:details[@"silent"]]) { content.sound = nil; } content.userInfo = [RCTConvert NSDictionary:details[@"userInfo"]] ?: @{}; content.categoryIdentifier = [RCTConvert NSString:details[@"category"]]; - + NSDate *triggerDate = [RCTConvert NSDate:details[@"fireDate"]]; UNCalendarNotificationTrigger *trigger = nil; - NSLog(@"ABOELBISHER : the fire date is %@", triggerDate); - if (triggerDate != nil) { NSDateComponents *triggerDateComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitYear + @@ -91,85 +134,44 @@ RCT_ENUM_CONVERTER(UNNotificationCategoryOptions, (@{ trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:triggerDateComponents repeats:NO]; } - + return [UNNotificationRequest requestWithIdentifier:notificationId content:content trigger:trigger]; } @end - -@implementation RCTConvert (UNNotificationCategory) -+ (UNNotificationCategory*) UNNotificationCategory:(id)json -{ - NSDictionary *details = [self NSDictionary:json]; - NSString* identefier = [RCTConvert NSString:details[@"identifier"]]; - - NSMutableArray* actions = [NSMutableArray new]; - for (NSDictionary* actionJson in [RCTConvert NSArray:details[@"actions"]]) - { - [actions addObject:[RCTConvert UNNotificationAction:actionJson]]; - } - - NSMutableArray* intentIdentifiers = [NSMutableArray new]; - for(NSDictionary* intentJson in [RCTConvert NSArray:details[@"intentIdentifiers"]]) - { - [intentIdentifiers addObject:[RCTConvert NSString:intentJson]]; - } - - UNNotificationCategory* cat = [UNNotificationCategory categoryWithIdentifier:identefier - actions:actions - intentIdentifiers:intentIdentifiers - options:[RCTConvert UNNotificationCategoryOptions:details[@"options"]]]; - return cat; -} -@end - static NSDictionary *RCTFormatUNNotification(UNNotification *notification) { - NSMutableDictionary *formattedNotification = [NSMutableDictionary dictionary]; - UNNotificationContent *content = notification.request.content; - - formattedNotification[@"identifier"] = notification.request.identifier; - - if (notification.date) { - NSDateFormatter *formatter = [NSDateFormatter new]; - [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"]; - NSString *dateString = [formatter stringFromDate:notification.date]; - formattedNotification[@"fireDate"] = dateString; - } - - formattedNotification[@"alertTitle"] = RCTNullIfNil(content.title); - formattedNotification[@"alertBody"] = RCTNullIfNil(content.body); - formattedNotification[@"category"] = RCTNullIfNil(content.categoryIdentifier); - formattedNotification[@"thread-id"] = RCTNullIfNil(content.threadIdentifier); - formattedNotification[@"userInfo"] = RCTNullIfNil(RCTJSONClean(content.userInfo)); - - return formattedNotification; -} - + NSMutableDictionary *formattedNotification = [NSMutableDictionary dictionary]; + UNNotificationContent *content = notification.request.content; -////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////// + formattedNotification[@"identifier"] = notification.request.identifier; -@interface RNNotifications() + if (notification.date) { + NSDateFormatter *formatter = [NSDateFormatter new]; + [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"]; + NSString *dateString = [formatter stringFromDate:notification.date]; + formattedNotification[@"fireDate"] = dateString; + } -@property(nonatomic) bool hasListeners; -@property(nonatomic) NSDictionary* openedNotification; + formattedNotification[@"alertTitle"] = RCTNullIfNil(content.title); + formattedNotification[@"alertBody"] = RCTNullIfNil(content.body); + formattedNotification[@"category"] = RCTNullIfNil(content.categoryIdentifier); + formattedNotification[@"thread-id"] = RCTNullIfNil(content.threadIdentifier); + formattedNotification[@"userInfo"] = RCTNullIfNil(RCTJSONClean(content.userInfo)); -@end + return formattedNotification; +} @implementation RNNotifications + RCT_EXPORT_MODULE() -- (instancetype)init +@synthesize bridge = _bridge; + +- (void)dealloc { - NSLog(@"ABOELBISHER : init"); - self = [super init]; - { - _hasListeners = NO; - [RNNRouter sharedInstance].delegate = self; - } - return self; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } + (BOOL)requiresMainQueueSetup { @@ -178,149 +180,96 @@ RCT_EXPORT_MODULE() - (void)setBridge:(RCTBridge *)bridge { - NSLog(@"ABOELBISHER : bridge set"); - [super setBridge:bridge]; - _openedNotification = [bridge.launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; - [RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification = [bridge.launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; - // UILocalNotification *localNotification = [bridge.launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; - // [RNNotificationsBridgeQueue sharedInstance].openedLocalNotification = localNotification ? localNotification.userInfo : nil; - -} + _bridge = bridge; -//////////////////////////////////////////////////////////////// -#pragma mark private functions -//////////////////////////////////////////////////////////////// + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handleNotificationsRegistered:) + name:RNNotificationsRegistered + object:nil]; -+ (void)requestPermissionsWithCategories:(NSMutableSet *)categories -{ - dispatch_async(dispatch_get_main_queue(), ^{ - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){ - if(!error) - { - if (granted) - { - dispatch_async(dispatch_get_main_queue(), ^{ - [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:categories]; - [[UIApplication sharedApplication] registerForRemoteNotifications]; - }); - } - } - }]; - }); -} - -//////////////////////////////////////////////////////////////// -#pragma mark NRNNManagerDelegate -//////////////////////////////////////////////////////////////// -//application:didReceiveLocalNotification : replacement - -//called when a notification is delivered to a foreground ap -- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler -{ - dispatch_async(dispatch_get_main_queue(), ^{ - - // //TODO: check WTF is this - // NSMutableDictionary* newUserInfo = notification.request.content.userInfo.mutableCopy; - // [newUserInfo removeObjectForKey:@"__id"]; - // notification.request.content.userInfo = newUserInfo; - // //// - - if (![RNNotificationsBridgeQueue sharedInstance].jsIsReady) - { - [RNNotificationsBridgeQueue sharedInstance].openedLocalNotification = notification.request.content.userInfo; - return; - } - - NSLog(@"ABOELBISHER : willPresentNotification"); - UIApplicationState state = [UIApplication sharedApplication].applicationState; - [self handleReceiveNotification:state userInfo:notification.request.content.userInfo]; - completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge); - }); + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handleNotificationsRegistrationFailed:) + name:RNNotificationsRegistrationFailed + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handlePushKitRegistered:) + name:RNPushKitRegistered + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handleNotificationReceivedForeground:) + name:RNNotificationReceivedForeground + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handleNotificationReceivedBackground:) + name:RNNotificationReceivedBackground + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handleNotificationOpened:) + name:RNNotificationOpened + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handleNotificationActionTriggered:) + name:RNNotificationActionTriggered + object:nil]; + + [RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification = [_bridge.launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; + UILocalNotification *localNotification = [_bridge.launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; + [RNNotificationsBridgeQueue sharedInstance].openedLocalNotification = localNotification ? localNotification.userInfo : nil; } -//called when a user selects an action in a delivered notification -- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler +/* + * Public Methods + */ ++ (void)didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { - NSString* identifier = response.actionIdentifier; - NSString* completionKey = [NSString stringWithFormat:@"%@.%@", identifier, [NSString stringWithFormat:@"%ld", (long)[[NSDate date] timeIntervalSince1970]]]; - NSMutableDictionary* info = [[NSMutableDictionary alloc] initWithDictionary:@{ @"identifier": identifier, @"completionKey": completionKey }]; - - // add text - NSString* text = ((UNTextInputNotificationResponse*)response).userText;//[response objectForKey:UIUserNotificationActionResponseTypedTextKey]; - if (text != NULL) { - info[@"text"] = text; - } - - NSDictionary* userInfo = response.notification.request.content.userInfo; - - // add notification custom data - if (userInfo != NULL) { - info[@"notification"] = userInfo; + if ([UIApplication instancesRespondToSelector:@selector(registerForRemoteNotifications)]) { + [[UIApplication sharedApplication] registerForRemoteNotifications]; } - - // Emit event to the queue (in order to store the completion handler). if JS thread is ready, post it also to the notification center (to the bridge). - [[RNNotificationsBridgeQueue sharedInstance] postAction:info withCompletionKey:completionKey andCompletionHandler:completionHandler]; - - if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady == YES) { - [self checkAndSendEvent:RNNotificationActionTriggered body:info]; - completionHandler(); - } else { - [RNNotificationsBridgeQueue sharedInstance].openedLocalNotification = info; - } - } -- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken ++ (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken { - NSString * str = [RNNotifications deviceTokenToString:deviceToken]; - [self checkAndSendEvent:RNNotificationsRegistered body:@{@"deviceToken":str}]; + NSString *tokenRepresentation = [deviceToken isKindOfClass:[NSString class]] ? deviceToken : [self deviceTokenToString:deviceToken]; + [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationsRegistered + object:self + userInfo:@{@"deviceToken": tokenRepresentation}]; } -- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error -{ - [self checkAndSendEvent:RNNotificationsRegistrationFailed - body:@{@"code": [NSNumber numberWithInteger:error.code], @"domain": error.domain, @"localizedDescription": error.localizedDescription}]; ++ (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { + [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationsRegistrationFailed + object:self + userInfo:@{@"code": [NSNumber numberWithInteger:error.code], @"domain": error.domain, @"localizedDescription": error.localizedDescription}]; } -//the system calls this method when your app is running in the foreground or background -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler ++ (void)didReceiveRemoteNotification:(NSDictionary *)notification { - if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady) { - dispatch_async(dispatch_get_main_queue(), ^{ - UIApplicationState state = [UIApplication sharedApplication].applicationState; - [self handleReceiveNotification:state userInfo:userInfo]; - }); - } else { - [[RNNotificationsBridgeQueue sharedInstance] postNotification:userInfo]; - } -} + UIApplicationState state = [UIApplication sharedApplication].applicationState; --(void) handleReceiveNotification:(UIApplicationState)state userInfo:(NSDictionary*)userInfo -{ - switch ((int)state) - { - case (int)UIApplicationStateActive: - [self checkAndSendEvent:RNNotificationReceivedForeground body:userInfo]; - - case (int)UIApplicationStateInactive: - [self checkAndSendEvent:RNNotificationOpened body:userInfo]; - - default: - [self checkAndSendEvent:RNNotificationReceivedBackground body:userInfo]; + if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady == YES) { + // JS thread is ready, push the notification to the bridge + + if (state == UIApplicationStateActive) { + // Notification received foreground + [self didReceiveNotificationOnForegroundState:notification]; + } else if (state == UIApplicationStateInactive) { + // Notification opened + [self didNotificationOpen:notification]; + } else { + // Notification received background + [self didReceiveNotificationOnBackgroundState:notification]; + } + } else { + // JS thread is not ready - store it in the native notifications queue + [[RNNotificationsBridgeQueue sharedInstance] postNotification:notification]; } } -- (void)handlePushKitRegistered:(NSDictionary *)notification -{ - [self checkAndSendEvent:RNPushKitRegistered body:notification]; -} - -//////////////////////////////////////////////////////////////// -#pragma mark ecents emitter side -//////////////////////////////////////////////////////////////// - -- (NSArray *)supportedEvents ++ (void)didReceiveLocalNotification:(UILocalNotification *)notification { return @[ RNNotificationsRegistered, @@ -342,93 +291,48 @@ RCT_EXPORT_MODULE() } } -- (void)stopObserving ++ (void)handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler { - _hasListeners = NO; + [self emitNotificationActionForIdentifier:identifier responseInfo:responseInfo userInfo:notification.userInfo completionHandler:completionHandler]; } -- (void)startObserving ++ (void)handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler { - _hasListeners = YES; -} - -//////////////////////////////////////////////////////////////// -#pragma mark exported method -//////////////////////////////////////////////////////////////// - -RCT_EXPORT_METHOD(requestPermissionsWithCategories:(NSArray *)json) -{ - NSMutableSet* categories = nil; - if ([json count] > 0) - { - categories = [NSMutableSet new]; - for (NSDictionary* dic in json) - { - [categories addObject:[RCTConvert UNNotificationCategory:dic]]; - } - } - [RNNotifications requestPermissionsWithCategories:categories]; -} - -RCT_EXPORT_METHOD(localNotification:(NSDictionary *)notification withId:(NSString *)notificationId) -{ - UNNotificationRequest* localNotification = [RCTConvert UNNotificationRequest:notification withId:notificationId]; - [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:localNotification withCompletionHandler:nil]; -} - -RCT_EXPORT_METHOD(cancelLocalNotification:(NSString *)notificationId) -{ - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center removePendingNotificationRequestsWithIdentifiers:@[notificationId]]; -} - -RCT_EXPORT_METHOD(abandonPermissions) -{ - [[UIApplication sharedApplication] unregisterForRemoteNotifications]; -} - -RCT_EXPORT_METHOD(getBadgesCount:(RCTResponseSenderBlock)callback) -{ - NSInteger count = [UIApplication sharedApplication].applicationIconBadgeNumber; - callback(@[ [NSNumber numberWithInteger:count] ]); -} - -RCT_EXPORT_METHOD(setBadgesCount:(int)count) -{ - [[UIApplication sharedApplication] setApplicationIconBadgeNumber:count]; + [self emitNotificationActionForIdentifier:identifier responseInfo:responseInfo userInfo:userInfo completionHandler:completionHandler]; } /* * Notification handlers */ -//+ (void)didReceiveNotificationOnForegroundState:(NSDictionary *)notification -//{ -// [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationReceivedForeground -// object:self -// userInfo:notification]; -//} ++ (void)didReceiveNotificationOnForegroundState:(NSDictionary *)notification +{ + [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationReceivedForeground + object:self + userInfo:notification]; +} --(void)didReceiveNotificationOnBackgroundState:(NSDictionary *)notification ++ (void)didReceiveNotificationOnBackgroundState:(NSDictionary *)notification { NSDictionary* managedAps = [notification objectForKey:@"managedAps"]; NSDictionary* alert = [managedAps objectForKey:@"alert"]; NSString* action = [managedAps objectForKey:@"action"]; NSString* notificationId = [managedAps objectForKey:@"notificationId"]; - + if (action) { // create or delete notification if ([action isEqualToString: RNNotificationCreateAction] && notificationId && alert) { [self dispatchLocalNotificationFromNotification:notification]; - + } else if ([action isEqualToString: RNNotificationClearAction] && notificationId) { [self clearNotificationFromNotificationsCenter:notificationId]; } } - - [self checkAndSendEvent:RNNotificationReceivedBackground body:notification]; - + + [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationReceivedBackground + object:self + userInfo:notification]; } + (void)didNotificationOpen:(NSDictionary *)notification @@ -441,17 +345,17 @@ RCT_EXPORT_METHOD(setBadgesCount:(int)count) /* * Helper methods */ --(void)dispatchLocalNotificationFromNotification:(NSDictionary *)notification ++ (void)dispatchLocalNotificationFromNotification:(NSDictionary *)notification { NSDictionary* managedAps = [notification objectForKey:@"managedAps"]; NSDictionary* alert = [managedAps objectForKey:@"alert"]; NSString* action = [managedAps objectForKey:@"action"]; NSString* notificationId = [managedAps objectForKey:@"notificationId"]; - + if ([action isEqualToString: RNNotificationCreateAction] && notificationId && alert) { - + // trigger new client push notification UILocalNotification* note = [UILocalNotification new]; note.alertTitle = [alert objectForKey:@"title"]; @@ -459,37 +363,37 @@ RCT_EXPORT_METHOD(setBadgesCount:(int)count) note.userInfo = notification; note.soundName = [managedAps objectForKey:@"sound"]; note.category = [managedAps objectForKey:@"category"]; - + [[UIApplication sharedApplication] presentLocalNotificationNow:note]; - + // Serialize it and store so we can delete it later NSData* data = [NSKeyedArchiver archivedDataWithRootObject:note]; NSString* notificationKey = [self buildNotificationKeyfromNotification:notificationId]; [[NSUserDefaults standardUserDefaults] setObject:data forKey:notificationKey]; [[NSUserDefaults standardUserDefaults] synchronize]; - + NSLog(@"Local notification was triggered: %@", notificationKey); } } --(void)clearNotificationFromNotificationsCenter:(NSString *)notificationId ++ (void)clearNotificationFromNotificationsCenter:(NSString *)notificationId { NSString* notificationKey = [self buildNotificationKeyfromNotification:notificationId]; NSData* data = [[NSUserDefaults standardUserDefaults] objectForKey:notificationKey]; if (data) { UILocalNotification* notification = [NSKeyedUnarchiver unarchiveObjectWithData: data]; - + // delete the notification [[UIApplication sharedApplication] cancelLocalNotification:notification]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:notificationKey]; - + NSLog(@"Local notification removed: %@", notificationKey); - + return; } } --(NSString *)buildNotificationKeyfromNotification:(NSString *)notificationId ++ (NSString *)buildNotificationKeyfromNotification:(NSString *)notificationId { return [NSString stringWithFormat:@"%@.%@", [[NSBundle mainBundle] bundleIdentifier], notificationId]; } @@ -502,43 +406,162 @@ RCT_EXPORT_METHOD(setBadgesCount:(int)count) for (NSUInteger i = 0; i < deviceTokenLength; i++) { [result appendFormat:@"%02x", bytes[i]]; } - + return [result copy]; } ++ (void)requestPermissionsWithCategories:(NSMutableSet *)categories +{ + UIUserNotificationType types = (UIUserNotificationType) (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert); + UIUserNotificationSettings* settings = [UIUserNotificationSettings settingsForTypes:types categories:categories]; + + [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; +} + ++ (void)emitNotificationActionForIdentifier:(NSString *)identifier responseInfo:(NSDictionary *)responseInfo userInfo:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler +{ + NSString* completionKey = [NSString stringWithFormat:@"%@.%@", identifier, [NSString stringWithFormat:@"%d", (long)[[NSDate date] timeIntervalSince1970]]]; + NSMutableDictionary* info = [[NSMutableDictionary alloc] initWithDictionary:@{ @"identifier": identifier, @"completionKey": completionKey }]; + + // add text + NSString* text = [responseInfo objectForKey:UIUserNotificationActionResponseTypedTextKey]; + if (text != NULL) { + info[@"text"] = text; + } + + // add notification custom data + if (userInfo != NULL) { + info[@"notification"] = userInfo; + } + + // Emit event to the queue (in order to store the completion handler). if JS thread is ready, post it also to the notification center (to the bridge). + [[RNNotificationsBridgeQueue sharedInstance] postAction:info withCompletionKey:completionKey andCompletionHandler:completionHandler]; + + if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady == YES) { + [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationActionTriggered + object:self + userInfo:info]; + } +} + ++ (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 + */ +- (void)handleNotificationsRegistered:(NSNotification *)notification +{ + [_bridge.eventDispatcher sendDeviceEventWithName:@"remoteNotificationsRegistered" body:notification.userInfo]; +} + +- (void)handleNotificationsRegistrationFailed:(NSNotification *)notification +{ + [_bridge.eventDispatcher sendDeviceEventWithName:@"remoteNotificationsRegistrationFailed" body:notification.userInfo]; +} + +- (void)handlePushKitRegistered:(NSNotification *)notification +{ + [_bridge.eventDispatcher sendDeviceEventWithName:@"pushKitRegistered" body:notification.userInfo]; +} + +- (void)handleNotificationReceivedForeground:(NSNotification *)notification +{ + [_bridge.eventDispatcher sendDeviceEventWithName:@"notificationReceivedForeground" body:notification.userInfo]; +} + +- (void)handleNotificationReceivedBackground:(NSNotification *)notification +{ + [_bridge.eventDispatcher sendDeviceEventWithName:@"notificationReceivedBackground" body:notification.userInfo]; +} + +- (void)handleNotificationOpened:(NSNotification *)notification +{ + [_bridge.eventDispatcher sendDeviceEventWithName:@"notificationOpened" body:notification.userInfo]; +} + +- (void)handleNotificationActionTriggered:(NSNotification *)notification +{ + [_bridge.eventDispatcher sendAppEventWithName:@"notificationActionReceived" body:notification.userInfo]; +} + /* * React Native exported methods */ +RCT_EXPORT_METHOD(requestPermissionsWithCategories:(NSArray *)json) +{ + NSMutableSet* categories = nil; + + if ([json count] > 0) { + categories = [NSMutableSet new]; + for (NSDictionary* categoryJson in json) { + [categories addObject:[RCTConvert UIMutableUserNotificationCategory:categoryJson]]; + } + } + + [RNNotifications requestPermissionsWithCategories:categories]; +} + RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { NSDictionary * notification = nil; notification = [RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification ? - [RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification : - [RNNotificationsBridgeQueue sharedInstance].openedLocalNotification; + [RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification : + [RNNotificationsBridgeQueue sharedInstance].openedLocalNotification; [RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification = nil; [RNNotificationsBridgeQueue sharedInstance].openedLocalNotification = nil; resolve(notification); } +RCT_EXPORT_METHOD(log:(NSString *)message) +{ + NSLog(message); +} + RCT_EXPORT_METHOD(completionHandler:(NSString *)completionKey) { [[RNNotificationsBridgeQueue sharedInstance] completeAction:completionKey]; } -RCT_EXPORT_METHOD(registerPushKit) +RCT_EXPORT_METHOD(abandonPermissions) { - dispatch_async(dispatch_get_main_queue(), ^{ - // 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]; - }); + [[UIApplication sharedApplication] unregisterForRemoteNotifications]; } +RCT_EXPORT_METHOD(registerPushKit) +{ + [RNNotifications registerPushKit]; +} +RCT_EXPORT_METHOD(getBadgesCount:(RCTResponseSenderBlock)callback) +{ + NSInteger count = [UIApplication sharedApplication].applicationIconBadgeNumber; + callback(@[ [NSNumber numberWithInteger:count] ]); +} +RCT_EXPORT_METHOD(setBadgesCount:(int)count) +{ + [[UIApplication sharedApplication] setApplicationIconBadgeNumber:count]; +} RCT_EXPORT_METHOD(backgroundTimeRemaining:(RCTResponseSenderBlock)callback) { @@ -550,32 +573,68 @@ RCT_EXPORT_METHOD(consumeBackgroundQueue) { // Mark JS Thread as ready [RNNotificationsBridgeQueue sharedInstance].jsIsReady = YES; - + // Push actions to JS [[RNNotificationsBridgeQueue sharedInstance] consumeActionsQueue:^(NSDictionary* action) { - [self checkAndSendEvent:RNNotificationActionReceived body:action]; + [[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationActionTriggered + object:self + userInfo:action]; }]; - + // Push background notifications to JS [[RNNotificationsBridgeQueue sharedInstance] consumeNotificationsQueue:^(NSDictionary* notification) { - [self didReceiveNotificationOnBackgroundState:notification]; + [RNNotifications didReceiveNotificationOnBackgroundState:notification]; }]; - + // Push opened local notifications NSDictionary* openedLocalNotification = [RNNotificationsBridgeQueue sharedInstance].openedLocalNotification; if (openedLocalNotification) { [RNNotificationsBridgeQueue sharedInstance].openedLocalNotification = nil; - [self checkAndSendEvent:RNNotificationOpened body:openedLocalNotification]; + [RNNotifications didNotificationOpen:openedLocalNotification]; } - + // Push opened remote notifications NSDictionary* openedRemoteNotification = [RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification; if (openedRemoteNotification) { [RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification = nil; - [self checkAndSendEvent:RNNotificationOpened body:openedRemoteNotification]; + [RNNotifications didNotificationOpen:openedRemoteNotification]; + } +} + +RCT_EXPORT_METHOD(localNotification:(NSDictionary *)notification withId:(NSString *)notificationId) +{ + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10")) { + UNNotificationRequest* localNotification = [RCTConvert UNNotificationRequest:notification withId:notificationId]; + [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:localNotification withCompletionHandler:nil]; + } else { + UILocalNotification* localNotification = [RCTConvert UILocalNotification:notification]; + NSMutableArray* userInfo = localNotification.userInfo.mutableCopy; + [userInfo setValue:notificationId forKey:@"__id"]; + localNotification.userInfo = userInfo; + + if ([notification objectForKey:@"fireDate"] != nil) { + [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; + } else { + [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification]; + } } } +RCT_EXPORT_METHOD(cancelLocalNotification:(NSString *)notificationId) +{ + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10")) { + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removePendingNotificationRequestsWithIdentifiers:@[notificationId]]; + } else { + for (UILocalNotification* notification in [UIApplication sharedApplication].scheduledLocalNotifications) { + NSDictionary* notificationInfo = notification.userInfo; + + if ([[notificationInfo objectForKey:@"__id"] isEqualToString:notificationId]) { + [[UIApplication sharedApplication] cancelLocalNotification:notification]; + } + } + } +} RCT_EXPORT_METHOD(cancelAllLocalNotifications) { @@ -584,14 +643,7 @@ RCT_EXPORT_METHOD(cancelAllLocalNotifications) RCT_EXPORT_METHOD(isRegisteredForRemoteNotifications:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { - BOOL ans; - - if (TARGET_IPHONE_SIMULATOR) { - ans = [[[UIApplication sharedApplication] currentUserNotificationSettings] types] != 0; - } - else { - ans = [[UIApplication sharedApplication] isRegisteredForRemoteNotifications]; - } + BOOL ans = [[[UIApplication sharedApplication] currentUserNotificationSettings] types] != 0; resolve(@(ans)); } @@ -609,33 +661,33 @@ RCT_EXPORT_METHOD(checkPermissions:(RCTPromiseResolveBlock) resolve RCT_EXPORT_METHOD(removeAllDeliveredNotifications) { - if ([UNUserNotificationCenter class]) { - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center removeAllDeliveredNotifications]; - } + if ([UNUserNotificationCenter class]) { + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removeAllDeliveredNotifications]; + } } RCT_EXPORT_METHOD(removeDeliveredNotifications:(NSArray *)identifiers) { - if ([UNUserNotificationCenter class]) { - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center removeDeliveredNotificationsWithIdentifiers:identifiers]; - } + if ([UNUserNotificationCenter class]) { + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removeDeliveredNotificationsWithIdentifiers:identifiers]; + } } RCT_EXPORT_METHOD(getDeliveredNotifications:(RCTResponseSenderBlock)callback) { - if ([UNUserNotificationCenter class]) { - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center getDeliveredNotificationsWithCompletionHandler:^(NSArray * _Nonnull notifications) { - NSMutableArray *formattedNotifications = [NSMutableArray new]; - - for (UNNotification *notification in notifications) { - [formattedNotifications addObject:RCTFormatUNNotification(notification)]; - } - callback(@[formattedNotifications]); - }]; - } + if ([UNUserNotificationCenter class]) { + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center getDeliveredNotificationsWithCompletionHandler:^(NSArray * _Nonnull notifications) { + NSMutableArray *formattedNotifications = [NSMutableArray new]; + + for (UNNotification *notification in notifications) { + [formattedNotifications addObject:RCTFormatUNNotification(notification)]; + } + callback(@[formattedNotifications]); + }]; + } } #endif !TARGET_OS_TV diff --git a/RNNotifications/RNNotifications.xcodeproj/project.pbxproj b/RNNotifications/RNNotifications.xcodeproj/project.pbxproj index f711c8b8410709afde890040bdd1b338ee8545bb..761eb17d0e7b357ae2f91fcb63cfd9d21e03e78a 100644 --- a/RNNotifications/RNNotifications.xcodeproj/project.pbxproj +++ b/RNNotifications/RNNotifications.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 432801F221F09C0F00A81AC2 /* RNNRouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 432801F021F09C0F00A81AC2 /* RNNRouter.m */; }; D85B37451CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D85B37441CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m */; }; D8A2F7551CB57F1A002CC8F5 /* RNNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */; }; /* End PBXBuildFile section */ @@ -26,8 +25,6 @@ /* Begin PBXFileReference section */ 134814201AA4EA6300B7C361 /* libRNNotifications.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNNotifications.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 432801F021F09C0F00A81AC2 /* RNNRouter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNRouter.m; sourceTree = ""; }; - 432801F121F09C0F00A81AC2 /* RNNRouter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNRouter.h; sourceTree = ""; }; D85B37441CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNotificationsBridgeQueue.m; sourceTree = ""; }; D85B37461CC05A1200DE9EB6 /* RNNotificationsBridgeQueue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNotificationsBridgeQueue.h; sourceTree = ""; }; D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNotifications.m; sourceTree = ""; }; @@ -60,8 +57,6 @@ D85B37441CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m */, D8A2F7561CB57F28002CC8F5 /* RNNotifications.h */, D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */, - 432801F121F09C0F00A81AC2 /* RNNRouter.h */, - 432801F021F09C0F00A81AC2 /* RNNRouter.m */, 134814211AA4EA7D00B7C361 /* Products */, ); sourceTree = ""; @@ -124,7 +119,6 @@ files = ( D8A2F7551CB57F1A002CC8F5 /* RNNotifications.m in Sources */, D85B37451CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m in Sources */, - 432801F221F09C0F00A81AC2 /* RNNRouter.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/RNNotifications/RNNotifications.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/RNNotifications/RNNotifications.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 919434a6254f0e9651f402737811be6634a03e9c..94b2795e225da4a26d84167bc90b2474092a7f03 100644 --- a/RNNotifications/RNNotifications.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/RNNotifications/RNNotifications.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -1,7 +1,4 @@ - - diff --git a/RNNotifications/RNNotifications.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/RNNotifications/RNNotifications.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d68d0546c4804ac2ff47dd97c6e7921..0000000000000000000000000000000000000000 --- a/RNNotifications/RNNotifications.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/docs/installation.md b/docs/installation.md index 42d4347c5beb7e805740bb938fd4e3be431ab028..12e33d02f92935ae76e33dda9d687980e06d4de5 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -17,48 +17,36 @@ First, [Manually link](https://facebook.github.io/react-native/docs/linking-libr Then, to enable notifications support add the following line at the top of your `AppDelegate.m` ```objective-c -#import "RNNRouter.h" +#import "RNNotifications.h" ``` And the following methods to support registration and receiving notifications: ```objective-c // Required to register for notifications -/ PushKit API Example -- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type +- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { - [[RNNRouter sharedInstance] didUpdatePushCredentials:credentials forType:type]; -} - -- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type -{ - [[RNNRouter sharedInstance] application:nil didReceiveRemoteNotification:payload.dictionaryPayload fetchCompletionHandler:nil]; -} - -- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error -{ - [[RNNRouter sharedInstance] application:application didFailToRegisterForRemoteNotificationsWithError:error]; + [RNNotifications didRegisterUserNotificationSettings:notificationSettings]; } - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { - [[RNNRouter sharedInstance] application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; + [RNNotifications didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } -// Required for the notification event. -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification -{ - [[RNNRouter sharedInstance] application:application didReceiveRemoteNotification:notification fetchCompletionHandler:nil]; +- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { + [RNNotifications didFailToRegisterForRemoteNotificationsWithError:error]; } -- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler -{ - [[RNNRouter sharedInstance] userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler]; +// Required for the notification event. +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification { + [RNNotifications didReceiveRemoteNotification:notification]; } -- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler +// Required for the localNotification event. +- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { - [[RNNRouter sharedInstance] userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler]; + [RNNotifications didReceiveLocalNotification:notification]; } ``` diff --git a/example/ios/NotificationsExampleApp/AppDelegate.h b/example/ios/NotificationsExampleApp/AppDelegate.h index 62190c87338fa0222dc123ea9f53712a04e7f119..1f298493ac1c6395a3e7927ed4dd7a9aa25dc5cc 100644 --- a/example/ios/NotificationsExampleApp/AppDelegate.h +++ b/example/ios/NotificationsExampleApp/AppDelegate.h @@ -10,9 +10,8 @@ #import #import -@import UserNotifications; -@interface AppDelegate : UIResponder +@interface AppDelegate : UIResponder @property (nonatomic, strong) UIWindow *window; diff --git a/example/ios/NotificationsExampleApp/AppDelegate.m b/example/ios/NotificationsExampleApp/AppDelegate.m index 00223f0c5fe7dc7e5221cbd032e4c34954c50a0f..1c5cbc77a26c4db52ef78be7e30d6b2bd99ad531 100644 --- a/example/ios/NotificationsExampleApp/AppDelegate.m +++ b/example/ios/NotificationsExampleApp/AppDelegate.m @@ -12,7 +12,7 @@ #import "RCTBundleURLProvider.h" #import "RCTRootView.h" #import "RNNotifications.h" -#import "RNNRouter.h" + #import @implementation AppDelegate @@ -20,60 +20,68 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSURL *jsCodeLocation; - + jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; - + RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"NotificationsExampleApp" initialProperties:nil launchOptions:launchOptions]; rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; - + self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; - [UNUserNotificationCenter currentNotificationCenter].delegate = self; - return YES; } // PushKit API Example - (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type { - [[RNNRouter sharedInstance] didUpdatePushCredentials:credentials forType:type]; + [RNNotifications didUpdatePushCredentials:credentials forType:type]; } - (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type { - [[RNNRouter sharedInstance] application:nil didReceiveRemoteNotification:payload.dictionaryPayload fetchCompletionHandler:nil]; + [RNNotifications didReceiveRemoteNotification:payload.dictionaryPayload]; } -- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error + +// Required to register for notifications +- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { - [[RNNRouter sharedInstance] application:application didFailToRegisterForRemoteNotificationsWithError:error]; + [RNNotifications didRegisterUserNotificationSettings:notificationSettings]; } - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { - [[RNNRouter sharedInstance] application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; + [RNNotifications didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } + // Required for the notification event. -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification { + [RNNotifications didReceiveRemoteNotification:notification]; +} + +// Required for the localNotification event. +- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { - [[RNNRouter sharedInstance] application:application didReceiveRemoteNotification:notification fetchCompletionHandler:nil]; + [RNNotifications didReceiveLocalNotification:notification]; } -- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler + +// Required for the notification actions. +- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler { - [[RNNRouter sharedInstance] userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler]; + [RNNotifications handleActionWithIdentifier:identifier forLocalNotification:notification withResponseInfo:responseInfo completionHandler:completionHandler]; } -- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler +- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler { - [[RNNRouter sharedInstance] userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler]; + [RNNotifications handleActionWithIdentifier:identifier forRemoteNotification:userInfo withResponseInfo:responseInfo completionHandler:completionHandler]; } @end diff --git a/example/package.json b/example/package.json index 59bc2798bb5f33b787aeca4600ee295ceeaa64c0..6efe80e79b6b34950a5bd5b3ea7c4e316814e43e 100644 --- a/example/package.json +++ b/example/package.json @@ -8,6 +8,6 @@ "dependencies": { "react": "16.8.3", "react-native": "0.59.x", - "react-native-notifications": "git://github.com/wix/react-native-notifications.git#iosDeprecationsFixes" + "react-native-notifications": "latest" } } diff --git a/index.ios.js b/index.ios.js index 8fe1dd9db1d67ae18b74a3473793fe7c84c35257..2108667328a7b8114e30e84a4b0b46dbdc2434bf 100644 --- a/index.ios.js +++ b/index.ios.js @@ -2,11 +2,10 @@ * @flow */ "use strict"; -import { NativeModules, NativeEventEmitter } from "react-native"; +import { NativeModules, DeviceEventEmitter, NativeAppEventEmitter } from "react-native"; import Map from "core-js/library/es6/map"; import uuid from "uuid"; -const {RNNotifications} = NativeModules; // eslint-disable-line no-unused-vars -const rnnotificationsEmitter = new NativeEventEmitter(RNNotifications); +const NativeRNNotifications = NativeModules.RNNotifications; // eslint-disable-line no-unused-vars import IOSNotification from "./notification.ios"; export const DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT = "remoteNotificationsRegistered"; @@ -65,22 +64,22 @@ export default class NotificationsIOS { let listener; if (type === DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT) { - listener = rnnotificationsEmitter.addListener( + listener = DeviceEventEmitter.addListener( DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT, registration => handler(registration.deviceToken) ); } else if (type === DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT) { - listener = rnnotificationsEmitter.addListener( + listener = DeviceEventEmitter.addListener( DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT, error => handler(error) ); } else if (type === DEVICE_PUSH_KIT_REGISTERED_EVENT) { - listener = rnnotificationsEmitter.addListener( + listener = DeviceEventEmitter.addListener( DEVICE_PUSH_KIT_REGISTERED_EVENT, registration => handler(registration.pushKitToken) ); } else { - listener = rnnotificationsEmitter.addListener( + listener = DeviceEventEmitter.addListener( type, notification => handler(new IOSNotification(notification)) ); @@ -112,7 +111,7 @@ export default class NotificationsIOS { action.notification = new IOSNotification(action.notification); actionHandler(action, () => { - RNNotifications.completionHandler(action.completionKey); + NativeRNNotifications.completionHandler(action.completionKey); }); } } @@ -125,7 +124,7 @@ export default class NotificationsIOS { if (categories) { // subscribe once for all actions - _actionListener = rnnotificationsEmitter.addListener(DEVICE_NOTIFICATION_ACTION_RECEIVED, this._actionHandlerDispatcher.bind(this)); + _actionListener = NativeAppEventEmitter.addListener(DEVICE_NOTIFICATION_ACTION_RECEIVED, this._actionHandlerDispatcher.bind(this)); notificationCategories = categories.map(category => { return Object.assign({}, category.options, { @@ -139,14 +138,14 @@ export default class NotificationsIOS { }); } - RNNotifications.requestPermissionsWithCategories(notificationCategories); + NativeRNNotifications.requestPermissionsWithCategories(notificationCategories); } /** * Unregister for all remote notifications received via Apple Push Notification service. */ static abandonPermissions() { - RNNotifications.abandonPermissions(); + NativeRNNotifications.abandonPermissions(); } /** @@ -162,31 +161,31 @@ export default class NotificationsIOS { } static getBadgesCount(callback: Function) { - RNNotifications.getBadgesCount(callback); + NativeRNNotifications.getBadgesCount(callback); } static setBadgesCount(count: number) { - RNNotifications.setBadgesCount(count); + NativeRNNotifications.setBadgesCount(count); } static registerPushKit() { - RNNotifications.registerPushKit(); + NativeRNNotifications.registerPushKit(); } static backgroundTimeRemaining(callback: Function) { - RNNotifications.backgroundTimeRemaining(callback); + NativeRNNotifications.backgroundTimeRemaining(callback); } static consumeBackgroundQueue() { - RNNotifications.consumeBackgroundQueue(); + NativeRNNotifications.consumeBackgroundQueue(); } static log(message: string) { - RNNotifications.log(message); + NativeRNNotifications.log(message); } static async getInitialNotification() { - const notification = await RNNotifications.getInitialNotification(); + const notification = await NativeRNNotifications.getInitialNotification(); if (notification) { return new IOSNotification(notification); } else { @@ -210,32 +209,32 @@ export default class NotificationsIOS { */ static localNotification(notification: Object) { const notificationId = uuid.v4(); - RNNotifications.localNotification(notification, notificationId); + NativeRNNotifications.localNotification(notification, notificationId); return notificationId; } static cancelLocalNotification(notificationId: String) { - RNNotifications.cancelLocalNotification(notificationId); + NativeRNNotifications.cancelLocalNotification(notificationId); } static cancelAllLocalNotifications() { - RNNotifications.cancelAllLocalNotifications(); + NativeRNNotifications.cancelAllLocalNotifications(); } static isRegisteredForRemoteNotifications() { - return RNNotifications.isRegisteredForRemoteNotifications(); + return NativeRNNotifications.isRegisteredForRemoteNotifications(); } static checkPermissions() { - return RNNotifications.checkPermissions(); + return NativeRNNotifications.checkPermissions(); } /** * Remove all delivered notifications from Notification Center */ static removeAllDeliveredNotifications() { - return RNNotifications.removeAllDeliveredNotifications(); + return NativeRNNotifications.removeAllDeliveredNotifications(); } /** @@ -244,7 +243,7 @@ export default class NotificationsIOS { * @param identifiers Array of notification identifiers */ static removeDeliveredNotifications(identifiers: Array) { - return RNNotifications.removeDeliveredNotifications(identifiers); + return NativeRNNotifications.removeDeliveredNotifications(identifiers); } /** @@ -263,6 +262,6 @@ export default class NotificationsIOS { * - `fireDate` : The date and time when the system should deliver the notification. if not specified, the notification will be dispatched immediately. */ static getDeliveredNotifications(callback: (notifications: Array) => void) { - return RNNotifications.getDeliveredNotifications(callback); + return NativeRNNotifications.getDeliveredNotifications(callback); } } diff --git a/package.json b/package.json index 178f10f7bbe05353392ca6700a42f6210368a8e8..b1af5112f94fa634c65d2a068d6d2f0b38a8db6b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-notifications", - "version": "1.4.1", + "version": "1.5.0", "description": "Advanced Push Notifications (Silent, interactive notifications) for iOS & Android", "author": "Lidan Hifi ", "license": "MIT", diff --git a/test/index.ios.spec.js b/test/index.ios.spec.js index 1b33f6155b473609772a429f551823fa9068aceb..295a3b672ac841c18484413f61e8e02966eefd26 100644 --- a/test/index.ios.spec.js +++ b/test/index.ios.spec.js @@ -18,6 +18,8 @@ describe("NotificationsIOS", () => { /*eslint-disable indent*/ let deviceAddEventListener, deviceRemoveEventListener, + nativeAppAddEventListener, + nativeAppRemoveEventListener, nativeRequestPermissionsWithCategories, nativeAbandonPermissions, nativeRegisterPushKit, @@ -35,8 +37,7 @@ describe("NotificationsIOS", () => { nativeGetDeliveredNotifications; let NotificationsIOS, NotificationAction, NotificationCategory; - let someHandler = () => { - }; + let someHandler = () => {}; let constantGuid = "some-random-uuid"; let identifiers = ["some-random-uuid", "other-random-uuid"]; /*eslint-enable indent*/ @@ -44,6 +45,8 @@ describe("NotificationsIOS", () => { before(() => { deviceAddEventListener = sinon.spy(); deviceRemoveEventListener = sinon.spy(); + nativeAppAddEventListener = sinon.spy(); + nativeAppRemoveEventListener = sinon.spy(); nativeRequestPermissionsWithCategories = sinon.spy(); nativeAbandonPermissions = sinon.spy(); nativeRegisterPushKit = sinon.spy(); @@ -60,7 +63,6 @@ describe("NotificationsIOS", () => { nativeRemoveDeliveredNotifications = sinon.spy(); nativeGetDeliveredNotifications = sinon.spy(); - let libUnderTest = proxyquire("../index.ios", { "uuid": { v4: () => constantGuid @@ -85,12 +87,20 @@ describe("NotificationsIOS", () => { getDeliveredNotifications: nativeGetDeliveredNotifications } }, - NativeEventEmitter: () => ({ + NativeAppEventEmitter: { + addListener: (...args) => { + nativeAppAddEventListener(...args); + + return { remove: nativeAppRemoveEventListener }; + } + }, + DeviceEventEmitter: { addListener: (...args) => { deviceAddEventListener(...args); - return {remove: deviceRemoveEventListener}; + + return { remove: deviceRemoveEventListener }; } - }), + }, "@noCallThru": true } }); @@ -103,6 +113,8 @@ describe("NotificationsIOS", () => { afterEach(() => { deviceAddEventListener.reset(); deviceRemoveEventListener.reset(); + nativeAppAddEventListener.reset(); + nativeAppRemoveEventListener.reset(); nativeRequestPermissionsWithCategories.reset(); nativeAbandonPermissions.reset(); nativeRegisterPushKit.reset(); @@ -121,6 +133,8 @@ describe("NotificationsIOS", () => { after(() => { deviceAddEventListener = null; deviceRemoveEventListener = null; + nativeAppAddEventListener = null; + nativeAppRemoveEventListener = null; nativeRequestPermissionsWithCategories = null; nativeAbandonPermissions = null; nativeRegisterPushKit = null; @@ -186,8 +200,7 @@ describe("NotificationsIOS", () => { }; beforeEach(() => { - someAction = new NotificationAction(actionOpts, () => { - }); + someAction = new NotificationAction(actionOpts, () => {}); someCategory = new NotificationCategory({ identifier: "SOME_CATEGORY", @@ -213,11 +226,11 @@ describe("NotificationsIOS", () => { expect(nativeRequestPermissionsWithCategories).to.have.been.calledWith([]); }); - ("should subscribe to 'notificationActionReceived' event once, with a single event handler", () => { + it("should subscribe to 'notificationActionReceived' event once, with a single event handler", () => { NotificationsIOS.requestPermissions([someCategory]); - expect(deviceAddEventListener).to.have.been.calledOnce; - // expect(nativeAppAddEventListener).to.have.been.calledWith("notificationActionReceived", sinon.match.func); + expect(nativeAppAddEventListener).to.have.been.calledOnce; + expect(nativeAppAddEventListener).to.have.been.calledWith("notificationActionReceived", sinon.match.func); }); }); @@ -225,7 +238,7 @@ describe("NotificationsIOS", () => { it("should remove 'notificationActionReceived' event handler", () => { NotificationsIOS.resetCategories(); - expect(deviceRemoveEventListener).to.have.been.calledOnce; + expect(nativeAppRemoveEventListener).to.have.been.calledOnce; }); }); @@ -266,8 +279,7 @@ describe("NotificationsIOS", () => { describe("Get background remaining time", () => { it("should call native background remaining time method", () => { - let someCallback = (time) => { - }; + let someCallback = (time) => { }; NotificationsIOS.backgroundTimeRemaining(someCallback);