Commit 911765e2 authored by yogevbd's avatar yogevbd

WIP

parent 882775fb
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
"no-trailing-spaces": "error", "no-trailing-spaces": "error",
"quotes": [ "quotes": [
"error", "error",
"double" "single"
], ],
"semi": [ "semi": [
"error", "error",
......
#import "RCTConvert.h"
@import UserNotifications;
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;
}
@import UserNotifications;
@interface RCTConvert (UIUserNotificationActivationMode)
@end
@interface RCTConvert (UIUserNotificationActionContext)
@end
@interface RCTConvert (UIUserNotificationActionBehavior)
@end
@interface RCTConvert (UIMutableUserNotificationAction)
+ (UIMutableUserNotificationAction *)UIMutableUserNotificationAction:(id)json;
@end
@interface RCTConvert (UIMutableUserNotificationCategory)
+ (UIMutableUserNotificationCategory *)UIMutableUserNotificationCategory:(id)json;
@end
@interface RCTConvert (UILocalNotification)
+ (UILocalNotification *)UILocalNotification:(id)json;
@end
@interface RCTConvert (UNNotificationRequest)
+ (UNNotificationRequest *)UNNotificationRequest:(id)json withId:(NSString*)notificationId;
@end
#import "RCTConvert+Notifications.h"
/*
* Converters for Interactive Notifications
*/
@implementation RCTConvert (UIUserNotificationActivationMode)
RCT_ENUM_CONVERTER(UIUserNotificationActivationMode, (@{
@"foreground": @(UIUserNotificationActivationModeForeground),
@"background": @(UIUserNotificationActivationModeBackground)
}), UIUserNotificationActivationModeForeground, integerValue)
@end
@implementation RCTConvert (UIUserNotificationActionContext)
RCT_ENUM_CONVERTER(UIUserNotificationActionContext, (@{
@"default": @(UIUserNotificationActionContextDefault),
@"minimal": @(UIUserNotificationActionContextMinimal)
}), UIUserNotificationActionContextDefault, integerValue)
@end
@implementation RCTConvert (UIUserNotificationActionBehavior)
/* iOS 9 only */
RCT_ENUM_CONVERTER(UIUserNotificationActionBehavior, (@{
@"default": @(UIUserNotificationActionBehaviorDefault),
@"textInput": @(UIUserNotificationActionBehaviorTextInput)
}), UIUserNotificationActionBehaviorDefault, integerValue)
@end
@implementation RCTConvert (UIMutableUserNotificationAction)
+ (UIMutableUserNotificationAction *)UIMutableUserNotificationAction:(id)json
{
NSDictionary<NSString *, id> *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<NSString *, id> *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"]]];
return category;
}
@end
@implementation RCTConvert (UILocalNotification)
+ (UILocalNotification *)UILocalNotification:(id)json
{
NSDictionary<NSString *, id> *details = [self NSDictionary:json];
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
@implementation RCTConvert (UNNotificationRequest)
+ (UNNotificationRequest *)UNNotificationRequest:(id)json withId:(NSString*)notificationId
{
NSDictionary<NSString *, id> *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 = nil;
}
content.userInfo = [RCTConvert NSDictionary:details[@"userInfo"]] ?: @{};
content.categoryIdentifier = [RCTConvert NSString:details[@"category"]];
NSDate *triggerDate = [RCTConvert NSDate:details[@"fireDate"]];
UNCalendarNotificationTrigger *trigger = nil;
if (triggerDate != nil) {
NSDateComponents *triggerDateComponents = [[NSCalendar currentCalendar]
components:NSCalendarUnitYear +
NSCalendarUnitMonth + NSCalendarUnitDay +
NSCalendarUnitHour + NSCalendarUnitMinute +
NSCalendarUnitSecond + NSCalendarUnitTimeZone
fromDate:triggerDate];
trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:triggerDateComponents
repeats:NO];
}
return [UNNotificationRequest requestWithIdentifier:notificationId
content:content trigger:trigger];
}
@end
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
@interface RNBridgeModule : NSObject <RCTBridgeModule>
@end
#import "RNBridgeModule.h"
#import "RNCommandsHandler.h"
#import "RCTConvert+Notifications.h"
#import "RNNotificationsBridgeQueue.h"
#import "RNEventEmitter.h"
#import "RNNotifications.h"
@implementation RNBridgeModule {
RNCommandsHandler* _commandsHandler;
}
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE();
- (instancetype)init {
self = [super init];
_commandsHandler = [[RNCommandsHandler alloc] init];
return self;
}
- (dispatch_queue_t)methodQueue {
return dispatch_get_main_queue();
}
+ (BOOL)requiresMainQueueSetup {
return YES;
}
#pragma mark - JS interface
RCT_EXPORT_METHOD(requestPermissionsWithCategories:(NSArray *)json) {
[_commandsHandler requestPermissionsWithCategories:json];
}
RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
[_commandsHandler getInitialNotification:resolve reject:reject];
}
RCT_EXPORT_METHOD(completionHandler:(NSString *)completionKey) {
[_commandsHandler completionHandler:completionKey];
}
RCT_EXPORT_METHOD(abandonPermissions) {
[_commandsHandler abandonPermissions];
}
RCT_EXPORT_METHOD(registerPushKit) {
[_commandsHandler registerPushKit];
}
RCT_EXPORT_METHOD(getBadgesCount:(RCTResponseSenderBlock)callback) {
[_commandsHandler getBadgesCount:callback];
}
RCT_EXPORT_METHOD(setBadgesCount:(int)count) {
[_commandsHandler setBadgesCount:count];
}
RCT_EXPORT_METHOD(localNotification:(NSDictionary *)notification withId:(NSString *)notificationId) {
[_commandsHandler localNotification:notification withId:notificationId];
}
RCT_EXPORT_METHOD(cancelLocalNotification:(NSString *)notificationId) {
[_commandsHandler cancelLocalNotification:notificationId];
}
RCT_EXPORT_METHOD(cancelAllLocalNotifications) {
[_commandsHandler cancelAllLocalNotifications];
}
RCT_EXPORT_METHOD(isRegisteredForRemoteNotifications:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
[_commandsHandler isRegisteredForRemoteNotifications:resolve reject:reject];
}
RCT_EXPORT_METHOD(checkPermissions:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject) {
[_commandsHandler checkPermissions:resolve reject:reject];
}
#if !TARGET_OS_TV
RCT_EXPORT_METHOD(removeAllDeliveredNotifications) {
[_commandsHandler removeAllDeliveredNotifications];
}
RCT_EXPORT_METHOD(removeDeliveredNotifications:(NSArray<NSString *> *)identifiers) {
[_commandsHandler removeDeliveredNotifications:identifiers];
}
RCT_EXPORT_METHOD(getDeliveredNotifications:(RCTResponseSenderBlock)callback) {
[_commandsHandler getDeliveredNotifications:callback];
}
#endif
@end
#import <Foundation/Foundation.h>
#import <React/RCTBridge.h>
@interface RNCommandsHandler : NSObject
- (void)requestPermissionsWithCategories:(NSArray *)json;
- (void)getInitialNotification:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject;
- (void)completionHandler:(NSString *)completionKey;
- (void)abandonPermissions;
- (void)registerPushKit;
- (void)getBadgesCount:(RCTResponseSenderBlock)callback;
- (void)setBadgesCount:(int)count;
- (void)localNotification:(NSDictionary *)notification withId:(NSString *)notificationId;
- (void)cancelLocalNotification:(NSString *)notificationId;
- (void)cancelAllLocalNotifications;
- (void)isRegisteredForRemoteNotifications:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject;
- (void)checkPermissions:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject;
- (void)removeAllDeliveredNotifications;
- (void)removeDeliveredNotifications:(NSArray<NSString *> *)identifiers;
- (void)getDeliveredNotifications:(RCTResponseSenderBlock)callback;
@end
#import "RNCommandsHandler.h"
#import "RNNotifications.h"
#import "RNNotificationsBridgeQueue.h"
#import "RCTConvert+Notifications.h"
@implementation RNCommandsHandler
- (instancetype)init {
self = [super init];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(onJavaScriptLoaded)
name:RCTJavaScriptDidLoadNotification
object:nil];
return self;
}
- (void)onJavaScriptLoaded {
[RNNotificationsBridgeQueue sharedInstance].jsIsReady = YES;
}
- (void)requestPermissionsWithCategories:(NSArray *)json {
NSMutableSet* categories = nil;
if ([json count] > 0) {
categories = [NSMutableSet new];
for (NSDictionary* categoryJson in json) {
[categories addObject:[RCTConvert UIMutableUserNotificationCategory:categoryJson]];
}
}
[[RNNotifications sharedInstance] requestPermissionsWithCategories:categories];
}
- (void)getInitialNotification:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
NSDictionary * notification = nil;
notification = [RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification ?
[RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification :
[RNNotificationsBridgeQueue sharedInstance].openedLocalNotification;
[RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification = nil;
[RNNotificationsBridgeQueue sharedInstance].openedLocalNotification = nil;
resolve(notification);
}
- (void)completionHandler:(NSString *)completionKey {
[[RNNotificationsBridgeQueue sharedInstance] completeAction:completionKey];
}
- (void)abandonPermissions {
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
}
- (void)registerPushKit {
[[RNNotifications sharedInstance] registerPushKit];
}
- (void)getBadgesCount:(RCTResponseSenderBlock)callback {
NSInteger count = [UIApplication sharedApplication].applicationIconBadgeNumber;
callback(@[ [NSNumber numberWithInteger:count] ]);
}
- (void)setBadgesCount:(int)count {
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:count];
}
- (void)localNotification:(NSDictionary *)notification withId:(NSString *)notificationId {
UNNotificationRequest* localNotification = [RCTConvert UNNotificationRequest:notification withId:notificationId];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:localNotification withCompletionHandler:nil];
}
- (void)cancelLocalNotification:(NSString *)notificationId {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center removePendingNotificationRequestsWithIdentifiers:@[notificationId]];
}
- (void)cancelAllLocalNotifications {
[RCTSharedApplication() cancelAllLocalNotifications];
}
- (void)isRegisteredForRemoteNotifications:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
BOOL ans = [[[UIApplication sharedApplication] currentUserNotificationSettings] types] != 0;
resolve(@(ans));
}
- (void)checkPermissions:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
UIUserNotificationSettings *currentSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
resolve(@{
@"badge": @((currentSettings.types & UIUserNotificationTypeBadge) > 0),
@"sound": @((currentSettings.types & UIUserNotificationTypeSound) > 0),
@"alert": @((currentSettings.types & UIUserNotificationTypeAlert) > 0),
});
}
- (void)removeAllDeliveredNotifications {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center removeAllDeliveredNotifications];
}
- (void)removeDeliveredNotifications:(NSArray<NSString *> *)identifiers {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center removeDeliveredNotificationsWithIdentifiers:identifiers];
}
- (void)getDeliveredNotifications:(RCTResponseSenderBlock)callback {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
NSMutableArray<NSDictionary *> *formattedNotifications = [NSMutableArray new];
for (UNNotification *notification in notifications) {
[formattedNotifications addObject:RCTFormatUNNotification(notification)];
}
callback(@[formattedNotifications]);
}];
}
@end
#import "RCTEventEmitter.h"
static NSString* const Registered = @"remoteNotificationsRegistered";
static NSString* const RegistrationFailed = @"remoteNotificationsRegistrationFailed";
static NSString* const PushKitRegistered = @"pushKitRegistered";
static NSString* const NotificationReceivedForeground = @"notificationReceivedForeground";
static NSString* const NotificationReceivedBackground = @"notificationReceivedBackground";
static NSString* const NotificationOpened = @"notificationOpened";
static NSString* const NotificationActionReceived = @"notificationActionReceived";
@interface RNEventEmitter : RCTEventEmitter
+ (instancetype)sharedInstance;
+ (void)sendEvent:(NSString *)event body:(NSDictionary *)body;
@end
#import "RNEventEmitter.h"
@implementation RNEventEmitter
RCT_EXPORT_MODULE();
-(NSArray<NSString *> *)supportedEvents {
return @[Registered,
RegistrationFailed,
PushKitRegistered,
NotificationReceivedForeground,
NotificationReceivedBackground,
NotificationOpened,
NotificationActionReceived];
}
# pragma mark public
+ (instancetype)sharedInstance {
static RNEventEmitter *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[RNEventEmitter alloc] init];
});
return sharedInstance;
}
+ (void)sendEvent:(NSString *)event body:(NSDictionary *)body {
[[self sharedInstance] send:event body:body];
}
# pragma mark private
- (void)send:(NSString *)eventName body:(id)body {
if (self.bridge == nil) {
return;
}
[self sendEventWithName:eventName body:body];
}
@end
...@@ -2,18 +2,26 @@ ...@@ -2,18 +2,26 @@
#import <React/RCTBridgeModule.h> #import <React/RCTBridgeModule.h>
#import <PushKit/PushKit.h> #import <PushKit/PushKit.h>
@import UserNotifications;
@interface RNNotifications : NSObject <RCTBridgeModule> @interface RNNotifications : NSObject <RCTBridgeModule>
+ (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken; + (instancetype)sharedInstance;
+ (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
+ (void)didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings;
+ (void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type;
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification; - (void)requestPermissionsWithCategories:(NSMutableSet *)categories;
+ (void)didReceiveLocalNotification:(UILocalNotification *)notification; - (void)registerPushKit;
+ (void)handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler; - (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken;
+ (void)handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler; - (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
- (void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type;
//- (void)didReceiveRemoteNotification:(NSDictionary *)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;
- (void)didReceiveForegroundNotification:(UNNotification *)notification;
- (void)didReceiveNotificationResponse:(UNNotificationResponse *)response;
//- (void)setBadgeForNotification:(NSDictionary *)notification;
@end @end
...@@ -8,167 +8,27 @@ ...@@ -8,167 +8,27 @@
#import <React/RCTUtils.h> #import <React/RCTUtils.h>
#import "RNNotificationsBridgeQueue.h" #import "RNNotificationsBridgeQueue.h"
#import <UserNotifications/UserNotifications.h> #import <UserNotifications/UserNotifications.h>
#import "RNEventEmitter.h"
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
NSString* const RNNotificationCreateAction = @"CREATE"; NSString* const RNNotificationCreateAction = @"CREATE";
NSString* const RNNotificationClearAction = @"CLEAR"; NSString* const RNNotificationClearAction = @"CLEAR";
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";
/*
* Converters for Interactive Notifications
*/
@implementation RCTConvert (UIUserNotificationActivationMode)
RCT_ENUM_CONVERTER(UIUserNotificationActivationMode, (@{
@"foreground": @(UIUserNotificationActivationModeForeground),
@"background": @(UIUserNotificationActivationModeBackground)
}), UIUserNotificationActivationModeForeground, integerValue)
@end
@implementation RCTConvert (UIUserNotificationActionContext)
RCT_ENUM_CONVERTER(UIUserNotificationActionContext, (@{
@"default": @(UIUserNotificationActionContextDefault),
@"minimal": @(UIUserNotificationActionContextMinimal)
}), UIUserNotificationActionContextDefault, integerValue)
@end
@implementation RCTConvert (UIUserNotificationActionBehavior)
/* iOS 9 only */
RCT_ENUM_CONVERTER(UIUserNotificationActionBehavior, (@{
@"default": @(UIUserNotificationActionBehaviorDefault),
@"textInput": @(UIUserNotificationActionBehaviorTextInput)
}), UIUserNotificationActionBehaviorDefault, integerValue)
@end
@implementation RCTConvert (UIMutableUserNotificationAction)
+ (UIMutableUserNotificationAction *)UIMutableUserNotificationAction:(id)json
{
NSDictionary<NSString *, id> *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<NSString *, id> *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"]]];
return category;
}
@end
@implementation RCTConvert (UILocalNotification)
+ (UILocalNotification *)UILocalNotification:(id)json
{
NSDictionary<NSString *, id> *details = [self NSDictionary:json];
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
@implementation RCTConvert (UNNotificationRequest)
+ (UNNotificationRequest *)UNNotificationRequest:(id)json withId:(NSString*)notificationId
{
NSDictionary<NSString *, id> *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 = nil;
}
content.userInfo = [RCTConvert NSDictionary:details[@"userInfo"]] ?: @{};
content.categoryIdentifier = [RCTConvert NSString:details[@"category"]];
NSDate *triggerDate = [RCTConvert NSDate:details[@"fireDate"]];
UNCalendarNotificationTrigger *trigger = nil;
if (triggerDate != nil) {
NSDateComponents *triggerDateComponents = [[NSCalendar currentCalendar]
components:NSCalendarUnitYear +
NSCalendarUnitMonth + NSCalendarUnitDay +
NSCalendarUnitHour + NSCalendarUnitMinute +
NSCalendarUnitSecond + NSCalendarUnitTimeZone
fromDate:triggerDate];
trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:triggerDateComponents
repeats:NO];
}
return [UNNotificationRequest requestWithIdentifier:notificationId
content:content trigger:trigger];
}
@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;
}
@implementation RNNotifications @implementation RNNotifications
RCT_EXPORT_MODULE() RCT_EXPORT_MODULE()
@synthesize bridge = _bridge; @synthesize bridge = _bridge;
+ (instancetype)sharedInstance {
static RNNotifications *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[RNNotifications alloc] init];
});
return sharedInstance;
}
- (void)dealloc - (void)dealloc
{ {
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
...@@ -181,42 +41,6 @@ RCT_EXPORT_MODULE() ...@@ -181,42 +41,6 @@ RCT_EXPORT_MODULE()
- (void)setBridge:(RCTBridge *)bridge - (void)setBridge:(RCTBridge *)bridge
{ {
_bridge = bridge; _bridge = bridge;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleNotificationsRegistered:)
name:RNNotificationsRegistered
object:nil];
[[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]; [RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification = [_bridge.launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
UILocalNotification *localNotification = [_bridge.launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; UILocalNotification *localNotification = [_bridge.launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
[RNNotificationsBridgeQueue sharedInstance].openedLocalNotification = localNotification ? localNotification.userInfo : nil; [RNNotificationsBridgeQueue sharedInstance].openedLocalNotification = localNotification ? localNotification.userInfo : nil;
...@@ -225,91 +49,52 @@ RCT_EXPORT_MODULE() ...@@ -225,91 +49,52 @@ RCT_EXPORT_MODULE()
/* /*
* Public Methods * Public Methods
*/ */
+ (void)didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
if ([UIApplication instancesRespondToSelector:@selector(registerForRemoteNotifications)]) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}
+ (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken - (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken {
{
NSString *tokenRepresentation = [deviceToken isKindOfClass:[NSString class]] ? deviceToken : [self deviceTokenToString:deviceToken]; NSString *tokenRepresentation = [deviceToken isKindOfClass:[NSString class]] ? deviceToken : [self deviceTokenToString:deviceToken];
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationsRegistered [RNEventEmitter sendEvent:Registered body:@{@"deviceToken": tokenRepresentation}];
object:self
userInfo:@{@"deviceToken": tokenRepresentation}];
} }
+ (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { - (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationsRegistrationFailed [RNEventEmitter sendEvent:RegistrationFailed body:@{@"code": [NSNumber numberWithInteger:error.code], @"domain": error.domain, @"localizedDescription": error.localizedDescription}];
object:self
userInfo:@{@"code": [NSNumber numberWithInteger:error.code], @"domain": error.domain, @"localizedDescription": error.localizedDescription}];
} }
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification - (void)didReceiveForegroundNotification:(UNNotification *)notification {
{
UIApplicationState state = [UIApplication sharedApplication].applicationState;
if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady == YES) { if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady == YES) {
// JS thread is ready, push the notification to the bridge
if (state == UIApplicationStateActive) {
// Notification received foreground
[self didReceiveNotificationOnForegroundState:notification]; [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)didReceiveLocalNotification:(UILocalNotification *)notification - (void)didReceiveNotificationResponse:(UNNotificationResponse *)response {
{ if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady == YES && [response.actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier]) {
UIApplicationState state = [UIApplication sharedApplication].applicationState; [self didNotificationOpen:response.notification.request.content.userInfo];
NSMutableDictionary* newUserInfo = notification.userInfo.mutableCopy;
[newUserInfo removeObjectForKey:@"__id"];
notification.userInfo = newUserInfo;
if (state == UIApplicationStateActive) {
[self didReceiveNotificationOnForegroundState:notification.userInfo];
} else if (state == UIApplicationStateInactive) {
NSString* notificationId = [notification.userInfo objectForKey:@"notificationId"];
if (notificationId) {
[self clearNotificationFromNotificationsCenter:notificationId];
}
[self didNotificationOpen:notification.userInfo];
} }
} }
+ (void)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)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];
} }
- (void)setBadgeForNotification:(NSDictionary *)notification {
if ([[notification objectForKey:@"aps"] objectForKey:@"badge"]){
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:[[[notification objectForKey:@"aps"] objectForKey:@"badge"] intValue]];
}
}
/* /*
* Notification handlers * Notification handlers
*/ */
+ (void)didReceiveNotificationOnForegroundState:(NSDictionary *)notification - (void)didReceiveNotificationOnForegroundState:(UNNotification *)notification {
{ [RNEventEmitter sendEvent:NotificationReceivedForeground body:notification.request.content.userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationReceivedForeground
object:self
userInfo:notification];
} }
+ (void)didReceiveNotificationOnBackgroundState:(NSDictionary *)notification - (void)didReceiveNotificationOnBackgroundState:(NSDictionary *)notification {
{
NSDictionary* managedAps = [notification objectForKey:@"managedAps"]; NSDictionary* managedAps = [notification objectForKey:@"managedAps"];
NSDictionary* alert = [managedAps objectForKey:@"alert"]; NSDictionary* alert = [managedAps objectForKey:@"alert"];
NSString* action = [managedAps objectForKey:@"action"]; NSString* action = [managedAps objectForKey:@"action"];
...@@ -327,23 +112,17 @@ RCT_EXPORT_MODULE() ...@@ -327,23 +112,17 @@ RCT_EXPORT_MODULE()
} }
} }
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationReceivedBackground [RNEventEmitter sendEvent:NotificationReceivedBackground body:notification];
object:self
userInfo:notification];
} }
+ (void)didNotificationOpen:(NSDictionary *)notification - (void)didNotificationOpen:(NSDictionary *)notification {
{ [RNEventEmitter sendEvent:NotificationOpened body:notification];
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationOpened
object:self
userInfo:notification];
} }
/* /*
* Helper methods * Helper methods
*/ */
+ (void)dispatchLocalNotificationFromNotification:(NSDictionary *)notification - (void)dispatchLocalNotificationFromNotification:(NSDictionary *)notification {
{
NSDictionary* managedAps = [notification objectForKey:@"managedAps"]; NSDictionary* managedAps = [notification objectForKey:@"managedAps"];
NSDictionary* alert = [managedAps objectForKey:@"alert"]; NSDictionary* alert = [managedAps objectForKey:@"alert"];
NSString* action = [managedAps objectForKey:@"action"]; NSString* action = [managedAps objectForKey:@"action"];
...@@ -373,8 +152,7 @@ RCT_EXPORT_MODULE() ...@@ -373,8 +152,7 @@ RCT_EXPORT_MODULE()
} }
} }
+ (void)clearNotificationFromNotificationsCenter:(NSString *)notificationId - (void)clearNotificationFromNotificationsCenter:(NSString *)notificationId {
{
NSString* notificationKey = [self buildNotificationKeyfromNotification:notificationId]; NSString* notificationKey = [self buildNotificationKeyfromNotification:notificationId];
NSData* data = [[NSUserDefaults standardUserDefaults] objectForKey:notificationKey]; NSData* data = [[NSUserDefaults standardUserDefaults] objectForKey:notificationKey];
if (data) { if (data) {
...@@ -390,13 +168,11 @@ RCT_EXPORT_MODULE() ...@@ -390,13 +168,11 @@ RCT_EXPORT_MODULE()
} }
} }
+ (NSString *)buildNotificationKeyfromNotification:(NSString *)notificationId - (NSString *)buildNotificationKeyfromNotification:(NSString *)notificationId {
{
return [NSString stringWithFormat:@"%@.%@", [[NSBundle mainBundle] bundleIdentifier], notificationId]; return [NSString stringWithFormat:@"%@.%@", [[NSBundle mainBundle] bundleIdentifier], notificationId];
} }
+ (NSString *)deviceTokenToString:(NSData *)deviceToken - (NSString *)deviceTokenToString:(NSData *)deviceToken {
{
NSMutableString *result = [NSMutableString string]; NSMutableString *result = [NSMutableString string];
NSUInteger deviceTokenLength = deviceToken.length; NSUInteger deviceTokenLength = deviceToken.length;
const unsigned char *bytes = deviceToken.bytes; const unsigned char *bytes = deviceToken.bytes;
...@@ -407,16 +183,26 @@ RCT_EXPORT_MODULE() ...@@ -407,16 +183,26 @@ RCT_EXPORT_MODULE()
return [result copy]; return [result copy];
} }
+ (void)requestPermissionsWithCategories:(NSMutableSet *)categories - (void)requestPermissionsWithCategories:(NSMutableSet *)categories {
{ UNAuthorizationOptions authOptions = (UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert);
UIUserNotificationType types = (UIUserNotificationType) (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert); [UNUserNotificationCenter.currentNotificationCenter requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
UIUserNotificationSettings* settings = [UIUserNotificationSettings settingsForTypes:types categories:categories]; if (error) {
[[UIApplication sharedApplication] registerUserNotificationSettings:settings]; } else {
if (granted) {
[UNUserNotificationCenter.currentNotificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}];
} else {
}
}
}];
} }
+ (void)emitNotificationActionForIdentifier:(NSString *)identifier responseInfo:(NSDictionary *)responseInfo userInfo:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler - (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]]]; NSString* completionKey = [NSString stringWithFormat:@"%@.%@", identifier, [NSString stringWithFormat:@"%d", (long)[[NSDate date] timeIntervalSince1970]]];
NSMutableDictionary* info = [[NSMutableDictionary alloc] initWithDictionary:@{ @"identifier": identifier, @"completionKey": completionKey }]; NSMutableDictionary* info = [[NSMutableDictionary alloc] initWithDictionary:@{ @"identifier": identifier, @"completionKey": completionKey }];
...@@ -435,14 +221,11 @@ RCT_EXPORT_MODULE() ...@@ -435,14 +221,11 @@ RCT_EXPORT_MODULE()
[[RNNotificationsBridgeQueue sharedInstance] postAction:info withCompletionKey:completionKey andCompletionHandler:completionHandler]; [[RNNotificationsBridgeQueue sharedInstance] postAction:info withCompletionKey:completionKey andCompletionHandler:completionHandler];
if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady == YES) { if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady == YES) {
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationActionTriggered [RNEventEmitter sendEvent:NotificationActionReceived body:userInfo];
object:self
userInfo:info];
} }
} }
+ (void)registerPushKit - (void)registerPushKit {
{
// Create a push registry object // Create a push registry object
PKPushRegistry* pushKitRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()]; PKPushRegistry* pushKitRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
...@@ -451,242 +234,12 @@ RCT_EXPORT_MODULE() ...@@ -451,242 +234,12 @@ RCT_EXPORT_MODULE()
pushKitRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP]; pushKitRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
} }
+ (void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type - (void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {
{ [RNEventEmitter sendEvent:PushKitRegistered body:@{@"pushKitToken": [self deviceTokenToString:credentials.token]}];
[[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 - (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
{ // [RNNotifications didReceiveRemoteNotification:payload.dictionaryPayload];
[_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 = 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(abandonPermissions)
{
[[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)
{
NSTimeInterval remainingTime = [UIApplication sharedApplication].backgroundTimeRemaining;
callback(@[ [NSNumber numberWithDouble:remainingTime] ]);
}
RCT_EXPORT_METHOD(consumeBackgroundQueue)
{
// Mark JS Thread as ready
[RNNotificationsBridgeQueue sharedInstance].jsIsReady = YES;
// Push actions to JS
[[RNNotificationsBridgeQueue sharedInstance] consumeActionsQueue:^(NSDictionary* action) {
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationActionTriggered
object:self
userInfo:action];
}];
// Push background notifications to JS
[[RNNotificationsBridgeQueue sharedInstance] consumeNotificationsQueue:^(NSDictionary* notification) {
[RNNotifications didReceiveNotificationOnBackgroundState:notification];
}];
// Push opened local notifications
NSDictionary* openedLocalNotification = [RNNotificationsBridgeQueue sharedInstance].openedLocalNotification;
if (openedLocalNotification) {
[RNNotificationsBridgeQueue sharedInstance].openedLocalNotification = nil;
[RNNotifications didNotificationOpen:openedLocalNotification];
}
// Push opened remote notifications
NSDictionary* openedRemoteNotification = [RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification;
if (openedRemoteNotification) {
[RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification = nil;
[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)
{
[RCTSharedApplication() cancelAllLocalNotifications];
}
RCT_EXPORT_METHOD(isRegisteredForRemoteNotifications:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
{
BOOL ans = [[[UIApplication sharedApplication] currentUserNotificationSettings] types] != 0;
resolve(@(ans));
}
RCT_EXPORT_METHOD(checkPermissions:(RCTPromiseResolveBlock) resolve
reject:(RCTPromiseRejectBlock) reject) {
UIUserNotificationSettings *currentSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
resolve(@{
@"badge": @((currentSettings.types & UIUserNotificationTypeBadge) > 0),
@"sound": @((currentSettings.types & UIUserNotificationTypeSound) > 0),
@"alert": @((currentSettings.types & UIUserNotificationTypeAlert) > 0),
});
}
#if !TARGET_OS_TV
RCT_EXPORT_METHOD(removeAllDeliveredNotifications)
{
if ([UNUserNotificationCenter class]) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center removeAllDeliveredNotifications];
}
}
RCT_EXPORT_METHOD(removeDeliveredNotifications:(NSArray<NSString *> *)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<UNNotification *> * _Nonnull notifications) {
NSMutableArray<NSDictionary *> *formattedNotifications = [NSMutableArray new];
for (UNNotification *notification in notifications) {
[formattedNotifications addObject:RCTFormatUNNotification(notification)];
}
callback(@[formattedNotifications]);
}];
}
}
#endif !TARGET_OS_TV
@end @end
...@@ -7,6 +7,10 @@ ...@@ -7,6 +7,10 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
50351F8F22CD782F000713B3 /* RNEventEmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 50351F8E22CD782F000713B3 /* RNEventEmitter.m */; };
50351F9222CD7DF4000713B3 /* RNBridgeModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 50351F9122CD7DF4000713B3 /* RNBridgeModule.m */; };
50351F9522CD7FF1000713B3 /* RCTConvert+Notifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 50351F9422CD7FF1000713B3 /* RCTConvert+Notifications.m */; };
50351F9822CD8604000713B3 /* RNCommandsHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 50351F9722CD8604000713B3 /* RNCommandsHandler.m */; };
D85B37451CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D85B37441CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m */; }; D85B37451CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D85B37441CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m */; };
D8A2F7551CB57F1A002CC8F5 /* RNNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */; }; D8A2F7551CB57F1A002CC8F5 /* RNNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
...@@ -25,6 +29,14 @@ ...@@ -25,6 +29,14 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
134814201AA4EA6300B7C361 /* libRNNotifications.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNNotifications.a; sourceTree = BUILT_PRODUCTS_DIR; }; 134814201AA4EA6300B7C361 /* libRNNotifications.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNNotifications.a; sourceTree = BUILT_PRODUCTS_DIR; };
50351F8D22CD782F000713B3 /* RNEventEmitter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNEventEmitter.h; sourceTree = "<group>"; };
50351F8E22CD782F000713B3 /* RNEventEmitter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNEventEmitter.m; sourceTree = "<group>"; };
50351F9022CD7DF4000713B3 /* RNBridgeModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNBridgeModule.h; sourceTree = "<group>"; };
50351F9122CD7DF4000713B3 /* RNBridgeModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNBridgeModule.m; sourceTree = "<group>"; };
50351F9322CD7FF1000713B3 /* RCTConvert+Notifications.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+Notifications.h"; sourceTree = "<group>"; };
50351F9422CD7FF1000713B3 /* RCTConvert+Notifications.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+Notifications.m"; sourceTree = "<group>"; };
50351F9622CD8604000713B3 /* RNCommandsHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNCommandsHandler.h; sourceTree = "<group>"; };
50351F9722CD8604000713B3 /* RNCommandsHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNCommandsHandler.m; sourceTree = "<group>"; };
D85B37441CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNotificationsBridgeQueue.m; sourceTree = "<group>"; }; D85B37441CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNotificationsBridgeQueue.m; sourceTree = "<group>"; };
D85B37461CC05A1200DE9EB6 /* RNNotificationsBridgeQueue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNotificationsBridgeQueue.h; sourceTree = "<group>"; }; D85B37461CC05A1200DE9EB6 /* RNNotificationsBridgeQueue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNotificationsBridgeQueue.h; sourceTree = "<group>"; };
D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNotifications.m; sourceTree = "<group>"; }; D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNotifications.m; sourceTree = "<group>"; };
...@@ -53,10 +65,18 @@ ...@@ -53,10 +65,18 @@
58B511D21A9E6C8500147676 = { 58B511D21A9E6C8500147676 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
50351F9022CD7DF4000713B3 /* RNBridgeModule.h */,
50351F9122CD7DF4000713B3 /* RNBridgeModule.m */,
D85B37461CC05A1200DE9EB6 /* RNNotificationsBridgeQueue.h */, D85B37461CC05A1200DE9EB6 /* RNNotificationsBridgeQueue.h */,
D85B37441CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m */, D85B37441CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m */,
D8A2F7561CB57F28002CC8F5 /* RNNotifications.h */, D8A2F7561CB57F28002CC8F5 /* RNNotifications.h */,
D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */, D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */,
50351F8D22CD782F000713B3 /* RNEventEmitter.h */,
50351F8E22CD782F000713B3 /* RNEventEmitter.m */,
50351F9622CD8604000713B3 /* RNCommandsHandler.h */,
50351F9722CD8604000713B3 /* RNCommandsHandler.m */,
50351F9322CD7FF1000713B3 /* RCTConvert+Notifications.h */,
50351F9422CD7FF1000713B3 /* RCTConvert+Notifications.m */,
134814211AA4EA7D00B7C361 /* Products */, 134814211AA4EA7D00B7C361 /* Products */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -117,8 +137,12 @@ ...@@ -117,8 +137,12 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
50351F9822CD8604000713B3 /* RNCommandsHandler.m in Sources */,
D8A2F7551CB57F1A002CC8F5 /* RNNotifications.m in Sources */, D8A2F7551CB57F1A002CC8F5 /* RNNotifications.m in Sources */,
50351F8F22CD782F000713B3 /* RNEventEmitter.m in Sources */,
50351F9222CD7DF4000713B3 /* RNBridgeModule.m in Sources */,
D85B37451CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m in Sources */, D85B37451CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m in Sources */,
50351F9522CD7FF1000713B3 /* RCTConvert+Notifications.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import { NativeModules, DeviceEventEmitter, NativeAppEventEmitter } from "react-native"; import { NativeModules, DeviceEventEmitter, NativeAppEventEmitter } from "react-native";
import Map from "core-js/library/es6/map"; import Map from "core-js/library/es6/map";
import uuid from "uuid"; import uuid from "uuid";
const NativeRNNotifications = NativeModules.RNNotifications; // eslint-disable-line no-unused-vars const NativeRNNotifications = NativeModules.RNBridgeModule; // 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_REMOTE_NOTIFICATIONS_REGISTERED_EVENT = "remoteNotificationsRegistered";
...@@ -177,7 +177,7 @@ export default class NotificationsIOS { ...@@ -177,7 +177,7 @@ export default class NotificationsIOS {
} }
static consumeBackgroundQueue() { static consumeBackgroundQueue() {
NativeRNNotifications.consumeBackgroundQueue(); // NativeRNNotifications.consumeBackgroundQueue();
} }
static log(message: string) { static log(message: string) {
......
module.exports = {
projectRoot: `${__dirname}/example`,
watchFolders: [
__dirname
]
};
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -19,6 +19,11 @@ ...@@ -19,6 +19,11 @@
"actionable-notifications", "actionable-notifications",
"interactive-notifications" "interactive-notifications"
], ],
"scripts": {
"pretest": "./node_modules/.bin/eslint *.js test",
"test": "./node_modules/.bin/mocha --compilers js:babel-register --reporter spec \"test/*.spec.js\"",
"start": "node ./scripts/start"
},
"nativePackage": true, "nativePackage": true,
"dependencies": { "dependencies": {
"core-js": "^1.0.0", "core-js": "^1.0.0",
...@@ -38,12 +43,8 @@ ...@@ -38,12 +43,8 @@
"mocha": "^2.5.3", "mocha": "^2.5.3",
"proxyquire": "^1.7.4", "proxyquire": "^1.7.4",
"sinon": "^1.17.3", "sinon": "^1.17.3",
"sinon-chai": "^2.8.0" "sinon-chai": "^2.8.0",
}, "shell-utils": "1.x.x"
"scripts": {
"pretest": "./node_modules/.bin/eslint *.js test",
"test": "./node_modules/.bin/mocha --compilers js:babel-register --reporter spec \"test/*.spec.js\"",
"start": "npm run test --silent; ./node_modules/.bin/chokidar \"test/*.js\" \"*.js\" -c 'npm run test --silent' --silent"
}, },
"publishConfig": { "publishConfig": {
"registry": "https://registry.npmjs.org/" "registry": "https://registry.npmjs.org/"
......
const exec = require('shell-utils').exec;
run();
function run() {
exec.killPort(8081);
exec.execSync(`watchman watch-del-all || true`);
exec.execSync(`adb reverse tcp:8081 tcp:8081 || true`);
exec.execSync(`node ./node_modules/react-native/local-cli/cli.js start`);
}
...@@ -69,7 +69,7 @@ describe("NotificationsIOS", () => { ...@@ -69,7 +69,7 @@ describe("NotificationsIOS", () => {
}, },
"react-native": { "react-native": {
NativeModules: { NativeModules: {
RNNotifications: { RNBridgeModule: {
requestPermissionsWithCategories: nativeRequestPermissionsWithCategories, requestPermissionsWithCategories: nativeRequestPermissionsWithCategories,
abandonPermissions: nativeAbandonPermissions, abandonPermissions: nativeAbandonPermissions,
registerPushKit: nativeRegisterPushKit, registerPushKit: nativeRegisterPushKit,
...@@ -287,14 +287,6 @@ describe("NotificationsIOS", () => { ...@@ -287,14 +287,6 @@ describe("NotificationsIOS", () => {
}); });
}); });
describe("Consume background queue which holds background notificiations and actions until js thread is ready", () => {
it("should call native consume background queue method", () => {
NotificationsIOS.consumeBackgroundQueue();
expect(nativeConsumeBackgroundQueue).to.have.been.called;
});
});
describe("Dispatch local notification", () => { describe("Dispatch local notification", () => {
it("should return generated notification guid", () => { it("should return generated notification guid", () => {
expect(NotificationsIOS.localNotification({})).to.equal(constantGuid); expect(NotificationsIOS.localNotification({})).to.equal(constantGuid);
......
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