Commit 1c4b350b authored by Yogev Ben David's avatar Yogev Ben David Committed by GitHub

Merge pull request #342 from wix/newAPIChangesIOS

Migrate to new iOS api's, remove unnecessary api functions
parents 882775fb 9cd8f4ac
......@@ -2,7 +2,7 @@
"parser": "babel-eslint",
"env": {
"node": true,
"mocha": true,
"jest": true,
"es6": true
},
"extends": "eslint:recommended",
......@@ -18,7 +18,7 @@
"no-trailing-spaces": "error",
"quotes": [
"error",
"double"
"single"
],
"semi": [
"error",
......
......@@ -178,3 +178,7 @@ jspm_packages
# Optional REPL history
.node_repl_history
coverage/
package-lock.json
\ No newline at end of file
language: node_js
node_js:
- "7"
- "10"
#import "RCTConvert.h"
@import UserNotifications;
@interface RCTConvert (UIMutableUserNotificationAction)
+ (UIMutableUserNotificationAction *)UIMutableUserNotificationAction:(id)json;
@end
@interface RCTConvert (UNMutableUserNotificationCategory)
+ (UNNotificationCategory *)UNMutableUserNotificationCategory:(id)json;
@end
@interface RCTConvert (UNNotificationRequest)
+ (UNNotificationRequest *)UNNotificationRequest:(id)json withId:(NSString*)notificationId;
@end
@interface RCTConvert (UNNotification)
+ (NSDictionary *)UNNotificationPayload:(UNNotification *)notification;
@end
@interface RCTConvert (UNNotificationPresentationOptions)
+ (UNNotificationPresentationOptions)UNNotificationPresentationOptions:(id)json;
@end
#import "RCTConvert+RNNotifications.h"
@implementation RCTConvert (UIUserNotificationActivationMode)
RCT_ENUM_CONVERTER(UIUserNotificationActivationMode, (@{
@"foreground": @(UIUserNotificationActivationModeForeground),
@"background": @(UIUserNotificationActivationModeBackground)
}), UIUserNotificationActivationModeForeground, integerValue)
@end
@implementation RCTConvert (UNNotificationActionOptions)
+ (UNNotificationActionOptions)UNUserNotificationActionOptions:(id)json {
UNNotificationActionOptions options = UNNotificationActionOptionNone;
if ([json[@"activationMode"] isEqualToString:@"foreground"]) {
options = options | UNNotificationActionOptionForeground;
}
if ([RCTConvert BOOL:json[@"authenticationRequired"]]) {
options = options | UNNotificationActionOptionAuthenticationRequired;
}
if ([RCTConvert BOOL:json[@"destructive"]]) {
options = options | UNNotificationActionOptionDestructive;
}
return options;
}
@end
@implementation RCTConvert (UNMutableUserNotificationAction)
+ (UNNotificationAction *)UNMutableUserNotificationAction:(id)json {
UNNotificationAction* action;
NSDictionary<NSString *, id> *details = [self NSDictionary:json];
if (details[@"textInput"]) {
action = [UNTextInputNotificationAction actionWithIdentifier:details[@"identifier"] title:details[@"title"] options:[RCTConvert UNUserNotificationActionOptions:details] textInputButtonTitle:details[@"textInput"][@"buttonTitle"] textInputPlaceholder:details[@"textInput"][@"placeholder"]];
} else {
action = [UNNotificationAction actionWithIdentifier:details[@"identifier"] title:details[@"title"] options:[RCTConvert UNUserNotificationActionOptions:details]];
}
return action;
}
@end
@implementation RCTConvert (UNMutableUserNotificationCategory)
+ (UNNotificationCategory *)UNMutableUserNotificationCategory:(id)json {
NSDictionary<NSString *, id> *details = [self NSDictionary:json];
NSMutableArray* actions = [NSMutableArray new];
for (NSDictionary* actionJson in [RCTConvert NSArray:details[@"actions"]]) {
[actions addObject:[RCTConvert UNMutableUserNotificationAction:actionJson]];
}
UNNotificationCategory* category = [UNNotificationCategory categoryWithIdentifier:details[@"identifier"] actions:actions intentIdentifiers:@[] options:UNNotificationCategoryOptionNone];
return category;
}
@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[@"body"]];
content.title = [RCTConvert NSString:details[@"title"]];
content.sound = [RCTConvert NSString:details[@"sound"]]
? [UNNotificationSound soundNamed:[RCTConvert NSString:details[@"sound"]]]
: [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
@implementation RCTConvert (UNNotification)
+ (NSDictionary *)UNNotificationPayload:(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[@"date"] = dateString;
}
formattedNotification[@"title"] = RCTNullIfNil(content.title);
formattedNotification[@"body"] = RCTNullIfNil(content.body);
formattedNotification[@"category"] = RCTNullIfNil(content.categoryIdentifier);
formattedNotification[@"thread"] = RCTNullIfNil(content.threadIdentifier);
[formattedNotification addEntriesFromDictionary:RCTNullIfNil(RCTJSONClean(content.userInfo))];
return formattedNotification;
}
@end
@implementation RCTConvert (UNNotificationPresentationOptions)
+ (UNNotificationPresentationOptions)UNNotificationPresentationOptions:(id)json {
UNNotificationPresentationOptions options = UNNotificationPresentationOptionNone;
if ([RCTConvert BOOL:json[@"alert"]]) {
options = options | UNNotificationPresentationOptionAlert;
}
if ([RCTConvert BOOL:json[@"badge"]]) {
options = options | UNNotificationPresentationOptionBadge;
}
if ([RCTConvert BOOL:json[@"sound"]]) {
options = options | UNNotificationPresentationOptionSound;
}
return options;
}
@end
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
@interface RNBridgeModule : NSObject <RCTBridgeModule>
@end
#import "RNBridgeModule.h"
#import "RNCommandsHandler.h"
#import "RCTConvert+RNNotifications.h"
#import "RNNotificationsStore.h"
#import <React/RCTBridgeDelegate.h>
@implementation RNBridgeModule {
RNCommandsHandler* _commandsHandler;
}
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE();
- (instancetype)init {
self = [super init];
_commandsHandler = [[RNCommandsHandler alloc] init];
return self;
}
+ (BOOL)requiresMainQueueSetup {
return YES;
}
- (void)setBridge:(RCTBridge *)bridge {
_bridge = bridge;
if ([_bridge.launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]) {
[[RNNotificationsStore sharedInstance] setInitialNotification:[_bridge.launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]];
}
}
#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(finishHandlingAction:(NSString *)completionKey) {
[_commandsHandler finishHandlingAction:completionKey];
}
RCT_EXPORT_METHOD(finishPresentingNotification:(NSString *)completionKey presentingOptions:(NSDictionary *)presentingOptions) {
[_commandsHandler finishPresentingNotification:completionKey presentingOptions:presentingOptions];
}
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 sendLocalNotification: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>
#import "RNNotificationCenter.h"
@interface RNCommandsHandler : NSObject
- (instancetype)init;
- (void)requestPermissionsWithCategories:(NSArray *)json;
- (void)getInitialNotification:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject;
- (void)finishHandlingAction:(NSString *)completionKey;
- (void)finishPresentingNotification:(NSString *)completionKey presentingOptions:(NSDictionary *)presentingOptions;
- (void)abandonPermissions;
- (void)registerPushKit;
- (void)getBadgesCount:(RCTResponseSenderBlock)callback;
- (void)setBadgesCount:(int)count;
- (void)sendLocalNotification:(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 "RNNotificationsStore.h"
#import "RCTConvert+RNNotifications.h"
@implementation RNCommandsHandler {
RNNotificationCenter* _notificationCenter;
}
- (instancetype)init {
self = [super init];
_notificationCenter = [RNNotificationCenter new];
return self;
}
- (void)requestPermissionsWithCategories:(NSArray *)json {
[_notificationCenter requestPermissionsWithCategories:json];
}
- (void)getInitialNotification:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
resolve([[RNNotificationsStore sharedInstance] initialNotification]);
}
- (void)finishHandlingAction:(NSString *)completionKey {
[[RNNotificationsStore sharedInstance] completeAction:completionKey];
}
- (void)finishPresentingNotification:(NSString *)completionKey presentingOptions:(NSDictionary *)presentingOptions {
[[RNNotificationsStore sharedInstance] completePresentation:completionKey withPresentationOptions:[RCTConvert UNNotificationPresentationOptions:presentingOptions]];
}
- (void)abandonPermissions {
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
}
- (void)registerPushKit {
[RNNotifications startMonitorPushKitNotifications];
}
- (void)getBadgesCount:(RCTResponseSenderBlock)callback {
NSInteger count = [UIApplication sharedApplication].applicationIconBadgeNumber;
callback(@[ [NSNumber numberWithInteger:count] ]);
}
- (void)setBadgesCount:(int)count {
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:count];
}
- (void)sendLocalNotification:(NSDictionary *)notification withId:(NSString *)notificationId {
[_notificationCenter sendLocalNotification:notification withId:notificationId];
}
- (void)cancelLocalNotification:(NSString *)notificationId {
[_notificationCenter cancelLocalNotification:notificationId];
}
- (void)cancelAllLocalNotifications {
[_notificationCenter cancelAllLocalNotifications];
}
- (void)isRegisteredForRemoteNotifications:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
[_notificationCenter isRegisteredForRemoteNotifications:resolve];
}
- (void)checkPermissions:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
[_notificationCenter checkPermissions:resolve];
}
- (void)removeAllDeliveredNotifications {
[_notificationCenter removeAllDeliveredNotifications];
}
- (void)removeDeliveredNotifications:(NSArray<NSString *> *)identifiers {
[_notificationCenter removeDeliveredNotifications:identifiers];
}
- (void)getDeliveredNotifications:(RCTResponseSenderBlock)callback {
[_notificationCenter getDeliveredNotifications:callback];
}
@end
#import <React/RCTEventEmitter.h>
static NSString* const RNRegistered = @"remoteNotificationsRegistered";
static NSString* const RNRegistrationFailed = @"remoteNotificationsRegistrationFailed";
static NSString* const RNPushKitRegistered = @"pushKitRegistered";
static NSString* const RNNotificationReceivedForeground = @"notificationReceivedForeground";
static NSString* const RNNotificationOpened = @"notificationOpened";
static NSString* const RNPushKitNotificationReceived = @"pushKitNotificationReceived";
@interface RNEventEmitter : RCTEventEmitter <RCTBridgeModule>
+ (void)sendEvent:(NSString *)event body:(NSDictionary *)body;
@end
#import "RNEventEmitter.h"
@implementation RNEventEmitter
RCT_EXPORT_MODULE();
-(NSArray<NSString *> *)supportedEvents {
return @[RNRegistered,
RNRegistrationFailed,
RNPushKitRegistered,
RNNotificationReceivedForeground,
RNNotificationOpened,
RNPushKitNotificationReceived];
}
- (instancetype)init {
self = [super init];
for (NSString *event in [self supportedEvents]) {
[self addListener:event];
}
return self;
}
+ (BOOL)requiresMainQueueSetup {
return YES;
}
# pragma mark public
+ (void)sendEvent:(NSString *)event body:(NSDictionary *)body {
[[NSNotificationCenter defaultCenter] postNotificationName:event
object:self
userInfo:body];
}
# pragma mark private
- (void)startObserving {
for (NSString *event in [self supportedEvents]) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleNotification:)
name:event
object:nil];
}
}
- (void)stopObserving {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)handleNotification:(NSNotification *)notification {
[self sendEventWithName:notification.name body:notification.userInfo];
}
@end
#import <Foundation/Foundation.h>
#import <React/RCTBridge.h>
@import UserNotifications;
@interface RNNotificationCenter : NSObject
- (void)isRegisteredForRemoteNotifications:(RCTPromiseResolveBlock)resolve;
- (void)requestPermissionsWithCategories:(NSArray *)json;
- (void)checkPermissions:(RCTPromiseResolveBlock)resolve;
- (void)sendLocalNotification:(NSDictionary *)notification withId:(NSString *)notificationId;
- (void)cancelLocalNotification:(NSString *)notificationId;
- (void)removeAllDeliveredNotifications;
- (void)removeDeliveredNotifications:(NSArray<NSString *> *)identifiers;
- (void)getDeliveredNotifications:(RCTResponseSenderBlock)callback;
- (void)cancelAllLocalNotifications;
@end
#import "RNNotificationCenter.h"
#import "RCTConvert+RNNotifications.h"
@implementation RNNotificationCenter
- (void)requestPermissionsWithCategories:(NSArray *)json {
NSMutableSet<UNNotificationCategory *>* categories = nil;
if ([json count] > 0) {
categories = [NSMutableSet new];
for (NSDictionary* categoryJson in json) {
[categories addObject:[RCTConvert UNMutableUserNotificationCategory:categoryJson]];
}
}
[[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:categories];
UNAuthorizationOptions authOptions = (UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert);
[UNUserNotificationCenter.currentNotificationCenter requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (error) {
} else {
if (granted) {
[UNUserNotificationCenter.currentNotificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) {
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] registerForRemoteNotifications];
});
}
}];
} else {
}
}
}];
}
- (void)sendLocalNotification:(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)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:[RCTConvert UNNotificationPayload:notification]];
}
callback(@[formattedNotifications]);
}];
}
- (void)cancelAllLocalNotifications {
[[UNUserNotificationCenter currentNotificationCenter] removeAllPendingNotificationRequests];
}
- (void)isRegisteredForRemoteNotifications:(RCTPromiseResolveBlock)resolve {
[[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
if (settings.alertSetting == UNNotificationSettingEnabled || settings.soundSetting == UNNotificationSettingEnabled || settings.badgeSetting == UNNotificationSettingEnabled) {
resolve(@(YES));
} else {
resolve(@(NO));
}
}];
}
- (void)checkPermissions:(RCTPromiseResolveBlock)resolve {
[[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
resolve(@{
@"badge": @(settings.badgeSetting == UNNotificationSettingEnabled),
@"sound": @(settings.soundSetting == UNNotificationSettingEnabled),
@"alert": @(settings.alertSetting == UNNotificationSettingEnabled),
});
}];
}
@end
#import <Foundation/Foundation.h>
@import UserNotifications;
#import "RNNotificationEventHandler.h"
@interface RNNotificationCenterListener : NSObject <UNUserNotificationCenterDelegate>
- (instancetype)initWithNotificationEventHandler:(RNNotificationEventHandler *)notificationEventHandler;
@end
#import "RNNotificationCenterListener.h"
#import "RCTConvert+RNNotifications.h"
@implementation RNNotificationCenterListener {
RNNotificationEventHandler* _notificationEventHandler;
}
- (instancetype)initWithNotificationEventHandler:(RNNotificationEventHandler *)notificationEventHandler {
self = [super init];
_notificationEventHandler = notificationEventHandler;
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
return self;
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
[_notificationEventHandler didReceiveForegroundNotification:notification withCompletionHandler:completionHandler];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
[_notificationEventHandler didReceiveNotificationResponse:response completionHandler:completionHandler];
}
@end
#import <Foundation/Foundation.h>
@import UserNotifications;
#import "RNNotificationsStore.h"
#import "RNEventEmitter.h"
@interface RNNotificationEventHandler : NSObject
- (instancetype)initWithStore:(RNNotificationsStore *)store;
- (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken;
- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
- (void)didReceiveForegroundNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler;
- (void)didReceiveNotificationResponse:(UNNotificationResponse *)notificationResponse completionHandler:(void (^)())completionHandler;
@end
#import "RNNotificationEventHandler.h"
#import "RNEventEmitter.h"
#import "RNNotificationUtils.h"
#import "RCTConvert+RNNotifications.h"
#import "RNNotificationParser.h"
@implementation RNNotificationEventHandler {
RNNotificationsStore* _store;
}
- (instancetype)initWithStore:(RNNotificationsStore *)store {
self = [super init];
_store = store;
return self;
}
- (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken {
NSString *tokenRepresentation = [deviceToken isKindOfClass:[NSString class]] ? deviceToken : [RNNotificationUtils deviceTokenToString:deviceToken];
[RNEventEmitter sendEvent:RNRegistered body:@{@"deviceToken": tokenRepresentation}];
}
- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
[RNEventEmitter sendEvent:RNRegistrationFailed body:@{@"code": [NSNumber numberWithInteger:error.code], @"domain": error.domain, @"localizedDescription": error.localizedDescription}];
}
- (void)didReceiveForegroundNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
[_store setPresentationCompletionHandler:completionHandler withCompletionKey:notification.request.identifier];
[RNEventEmitter sendEvent:RNNotificationReceivedForeground body:[RNNotificationParser parseNotification:notification]];
}
- (void)didReceiveNotificationResponse:(UNNotificationResponse *)response completionHandler:(void (^)())completionHandler {
[_store setActionCompletionHandler:completionHandler withCompletionKey:response.notification.request.identifier];
[RNEventEmitter sendEvent:RNNotificationOpened body:[RNNotificationParser parseNotificationResponse:response]];
}
@end
#import <Foundation/Foundation.h>
@import UserNotifications;
@interface RNNotificationParser : NSObject
+ (NSDictionary *)parseNotificationResponse:(UNNotificationResponse *)response;
+ (NSDictionary *)parseNotification:(UNNotification *)notification;
@end
#import "RNNotificationParser.h"
#import "RCTConvert+RNNotifications.h"
@implementation RNNotificationParser
+ (NSDictionary *)parseNotification:(UNNotification *)notification {
NSDictionary* notificationDict = @{@"identifier": notification.request.identifier,
@"payload": [RCTConvert UNNotificationPayload:notification]
};
return notificationDict;
}
+ (NSDictionary *)parseNotificationResponse:(UNNotificationResponse *)response {
NSDictionary* responseDict = @{@"payload": [RCTConvert UNNotificationPayload:response.notification], @"identifier": response.notification.request.identifier, @"action": [self parseNotificationResponseAction:response]};
return responseDict;
}
+ (NSDictionary *)parseNotificationResponseAction:(UNNotificationResponse *)response {
NSMutableDictionary* responseAction = [NSMutableDictionary dictionaryWithDictionary:@{@"identifier": response.actionIdentifier}];
NSString* responseText = [response isKindOfClass:[UNTextInputNotificationResponse class]] ? ((UNTextInputNotificationResponse *)response).userText : nil;
if (responseText) {
[responseAction setObject:responseText forKey:@"text"];
}
return responseAction;
}
@end
#import <Foundation/Foundation.h>
@interface RNNotificationUtils : NSObject
+ (NSString *)deviceTokenToString:(NSData *)deviceToken;
@end
#import "RNNotificationUtils.h"
@implementation RNNotificationUtils
+ (NSString *)deviceTokenToString:(NSData *)deviceToken {
NSMutableString *result = [NSMutableString string];
NSUInteger deviceTokenLength = deviceToken.length;
const unsigned char *bytes = deviceToken.bytes;
for (NSUInteger i = 0; i < deviceTokenLength; i++) {
[result appendFormat:@"%02x", bytes[i]];
}
return [result copy];
}
@end
@import UIKit;
#import <React/RCTBridgeModule.h>
#import <PushKit/PushKit.h>
@import UserNotifications;
@interface RNNotifications : NSObject <RCTBridgeModule>
@interface RNNotifications : NSObject
+ (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken;
+ (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
+ (void)didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings;
+ (void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type;
+ (instancetype)sharedInstance;
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification;
+ (void)didReceiveLocalNotification:(UILocalNotification *)notification;
+ (void)startMonitorNotifications;
+ (void)startMonitorPushKitNotifications;
+ (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)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken;
+ (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
@end
......@@ -2,691 +2,65 @@
#import <UIKit/UIKit.h>
#import <PushKit/PushKit.h>
#import <React/RCTBridge.h>
#import <React/RCTEventDispatcher.h>
#import "RNNotifications.h"
#import <React/RCTConvert.h>
#import <React/RCTUtils.h>
#import "RNNotificationsBridgeQueue.h"
#import <UserNotifications/UserNotifications.h>
#import "RNNotificationCenterListener.h"
#import "RNPushKit.h"
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
NSString* const RNNotificationCreateAction = @"CREATE";
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;
@implementation RNNotifications {
RNPushKit* _pushKit;
RNNotificationCenterListener* _notificationCenterListener;
RNNotificationEventHandler* _notificationEventHandler;
RNPushKitEventHandler* _pushKitEventHandler;
RNEventEmitter* _eventEmitter;
}
@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;
- (instancetype)init {
self = [super init];
_notificationEventHandler = [[RNNotificationEventHandler alloc] initWithStore:[RNNotificationsStore new]];
return self;
}
@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;
+ (instancetype)sharedInstance {
static RNNotifications *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[RNNotifications alloc] init];
});
return sharedInstance;
}
@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];
+ (void)startMonitorNotifications {
[[self sharedInstance] startMonitorNotifications];
}
@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;
+ (void)startMonitorPushKitNotifications {
[[self sharedInstance] startMonitorPushKitNotifications];
}
@implementation RNNotifications
RCT_EXPORT_MODULE()
@synthesize bridge = _bridge;
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
+ (BOOL)requiresMainQueueSetup {
return YES;
}
- (void)setBridge:(RCTBridge *)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];
UILocalNotification *localNotification = [_bridge.launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
[RNNotificationsBridgeQueue sharedInstance].openedLocalNotification = localNotification ? localNotification.userInfo : nil;
}
/*
* Public Methods
*/
+ (void)didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
if ([UIApplication instancesRespondToSelector:@selector(registerForRemoteNotifications)]) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}
+ (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken
{
NSString *tokenRepresentation = [deviceToken isKindOfClass:[NSString class]] ? deviceToken : [self deviceTokenToString:deviceToken];
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationsRegistered
object:self
userInfo:@{@"deviceToken": tokenRepresentation}];
+ (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken {
[[self sharedInstance] didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
+ (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationsRegistrationFailed
object:self
userInfo:@{@"code": [NSNumber numberWithInteger:error.code], @"domain": error.domain, @"localizedDescription": error.localizedDescription}];
}
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification
{
UIApplicationState state = [UIApplication sharedApplication].applicationState;
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)didReceiveLocalNotification:(UILocalNotification *)notification
{
UIApplicationState state = [UIApplication sharedApplication].applicationState;
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
{
[self emitNotificationActionForIdentifier:identifier responseInfo:responseInfo userInfo:notification.userInfo completionHandler:completionHandler];
}
+ (void)handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler
{
[self emitNotificationActionForIdentifier:identifier responseInfo:responseInfo userInfo:userInfo completionHandler:completionHandler];
}
/*
* Notification handlers
*/
+ (void)didReceiveNotificationOnForegroundState:(NSDictionary *)notification
{
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationReceivedForeground
object:self
userInfo: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];
}
}
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationReceivedBackground
object:self
userInfo:notification];
}
+ (void)didNotificationOpen:(NSDictionary *)notification
{
[[NSNotificationCenter defaultCenter] postNotificationName:RNNotificationOpened
object:self
userInfo:notification];
}
/*
* Helper methods
*/
+ (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"];
note.alertBody = [alert objectForKey:@"body"];
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
{
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
{
return [NSString stringWithFormat:@"%@.%@", [[NSBundle mainBundle] bundleIdentifier], notificationId];
}
+ (NSString *)deviceTokenToString:(NSData *)deviceToken
{
NSMutableString *result = [NSMutableString string];
NSUInteger deviceTokenLength = deviceToken.length;
const unsigned char *bytes = deviceToken.bytes;
for (NSUInteger i = 0; i < deviceTokenLength; i++) {
[result appendFormat:@"%02x", bytes[i]];
}
return [result copy];
}
+ (void)requestPermissionsWithCategories:(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];
[[self sharedInstance] didFailToRegisterForRemoteNotificationsWithError:error];
}
+ (void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type
{
[[NSNotificationCenter defaultCenter] postNotificationName:RNPushKitRegistered
object:self
userInfo:@{@"pushKitToken": [self deviceTokenToString:credentials.token]}];
- (void)startMonitorNotifications {
_notificationCenterListener = [[RNNotificationCenterListener alloc] initWithNotificationEventHandler:_notificationEventHandler];
}
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
{
[RNNotifications didReceiveRemoteNotification:payload.dictionaryPayload];
- (void)startMonitorPushKitNotifications {
_pushKitEventHandler = [RNPushKitEventHandler new];
_pushKit = [[RNPushKit alloc] initWithEventHandler:_pushKitEventHandler];
}
/*
* Javascript events
*/
- (void)handleNotificationsRegistered:(NSNotification *)notification
{
[_bridge.eventDispatcher sendDeviceEventWithName:@"remoteNotificationsRegistered" body:notification.userInfo];
- (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken {
[_notificationEventHandler didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
- (void)handleNotificationsRegistrationFailed:(NSNotification *)notification
{
[_bridge.eventDispatcher sendDeviceEventWithName:@"remoteNotificationsRegistrationFailed" body:notification.userInfo];
- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
[_notificationEventHandler didFailToRegisterForRemoteNotificationsWithError:error];
}
- (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
......@@ -7,10 +7,49 @@
objects = {
/* Begin PBXBuildFile section */
D85B37451CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D85B37441CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m */; };
50351F8F22CD782F000713B3 /* RNEventEmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 50351F8E22CD782F000713B3 /* RNEventEmitter.m */; };
50351F9222CD7DF4000713B3 /* RNBridgeModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 50351F9122CD7DF4000713B3 /* RNBridgeModule.m */; };
50351F9522CD7FF1000713B3 /* RCTConvert+RNNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 50351F9422CD7FF1000713B3 /* RCTConvert+RNNotifications.m */; };
50351F9822CD8604000713B3 /* RNCommandsHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 50351F9722CD8604000713B3 /* RNCommandsHandler.m */; };
507DCCF522CE3EBD005D4E0B /* RNNotifications.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = D8A2F7561CB57F28002CC8F5 /* RNNotifications.h */; };
507DCCF722CE3EF7005D4E0B /* RNBridgeModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 50351F9022CD7DF4000713B3 /* RNBridgeModule.h */; };
507DCCF922CE3F04005D4E0B /* RNNotifications.h in Headers */ = {isa = PBXBuildFile; fileRef = D8A2F7561CB57F28002CC8F5 /* RNNotifications.h */; settings = {ATTRIBUTES = (Public, ); }; };
507DCCFA22CE3F04005D4E0B /* RNEventEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 50351F8D22CD782F000713B3 /* RNEventEmitter.h */; };
507DCCFB22CE3F04005D4E0B /* RNCommandsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 50351F9622CD8604000713B3 /* RNCommandsHandler.h */; };
507DCCFC22CE3F04005D4E0B /* RCTConvert+RNNotifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 50351F9322CD7FF1000713B3 /* RCTConvert+RNNotifications.h */; };
508CE7CB22D12B2600357815 /* RNNotificationsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 508CE7CA22D12B2600357815 /* RNNotificationsTests.m */; };
508CE7CD22D12B2600357815 /* libRNNotifications.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 134814201AA4EA6300B7C361 /* libRNNotifications.a */; };
508CE7D522D12CCA00357815 /* RNNotificationEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 508CE7D322D12CCA00357815 /* RNNotificationEventHandler.h */; };
508CE7D622D12CCA00357815 /* RNNotificationEventHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 508CE7D422D12CCA00357815 /* RNNotificationEventHandler.m */; };
508CE81422D12FC700357815 /* RNNotificationCenterListener.m in Sources */ = {isa = PBXBuildFile; fileRef = 508CE81322D12FC600357815 /* RNNotificationCenterListener.m */; };
508CE81622D12FF600357815 /* RNNotificationCenterListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 508CE81522D12FF500357815 /* RNNotificationCenterListener.h */; };
508CE81922D130B900357815 /* RNPushKitEventListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 508CE81722D130B900357815 /* RNPushKitEventListener.h */; };
508CE81A22D130B900357815 /* RNPushKitEventListener.m in Sources */ = {isa = PBXBuildFile; fileRef = 508CE81822D130B900357815 /* RNPushKitEventListener.m */; };
508CE81D22D1337200357815 /* RNPushKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 508CE81B22D1337200357815 /* RNPushKit.h */; };
508CE81E22D1337200357815 /* RNPushKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 508CE81C22D1337200357815 /* RNPushKit.m */; };
508CE82222D1372E00357815 /* RNNotificationUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 508CE82022D1372E00357815 /* RNNotificationUtils.h */; };
508CE82322D1372E00357815 /* RNNotificationUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 508CE82122D1372E00357815 /* RNNotificationUtils.m */; };
50AD1FCA22D13ADB00E12362 /* RNPushKitEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 50AD1FC822D13ADB00E12362 /* RNPushKitEventHandler.h */; };
50AD1FCB22D13ADB00E12362 /* RNPushKitEventHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 50AD1FC922D13ADB00E12362 /* RNPushKitEventHandler.m */; };
50E49F0722D1E4E0007160C1 /* RNNotificationsStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E49F0522D1E4E0007160C1 /* RNNotificationsStore.h */; };
50E49F0822D1E4E0007160C1 /* RNNotificationsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 50E49F0622D1E4E0007160C1 /* RNNotificationsStore.m */; };
50FED76622D3E06500DDD516 /* RNNotificationCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FED76422D3E06500DDD516 /* RNNotificationCenter.h */; };
50FED76722D3E06500DDD516 /* RNNotificationCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 50FED76522D3E06500DDD516 /* RNNotificationCenter.m */; };
50FED76E22D3EBA800DDD516 /* RNNotificationParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FED76C22D3EBA800DDD516 /* RNNotificationParser.h */; };
50FED76F22D3EBA800DDD516 /* RNNotificationParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 50FED76D22D3EBA800DDD516 /* RNNotificationParser.m */; };
D8A2F7551CB57F1A002CC8F5 /* RNNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
508CE7CE22D12B2600357815 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 58B511D31A9E6C8500147676 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 58B511DA1A9E6C8500147676;
remoteInfo = RNNotifications;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
58B511D91A9E6C8500147676 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
......@@ -18,6 +57,7 @@
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
507DCCF522CE3EBD005D4E0B /* RNNotifications.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -25,13 +65,48 @@
/* Begin PBXFileReference section */
134814201AA4EA6300B7C361 /* libRNNotifications.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNNotifications.a; sourceTree = BUILT_PRODUCTS_DIR; };
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>"; };
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+RNNotifications.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+RNNotifications.h"; sourceTree = "<group>"; };
50351F9422CD7FF1000713B3 /* RCTConvert+RNNotifications.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+RNNotifications.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>"; };
508CE7C822D12B2600357815 /* RNNotificationsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNNotificationsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
508CE7CA22D12B2600357815 /* RNNotificationsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNotificationsTests.m; sourceTree = "<group>"; };
508CE7CC22D12B2600357815 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
508CE7D322D12CCA00357815 /* RNNotificationEventHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNotificationEventHandler.h; sourceTree = "<group>"; };
508CE7D422D12CCA00357815 /* RNNotificationEventHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNotificationEventHandler.m; sourceTree = "<group>"; };
508CE81322D12FC600357815 /* RNNotificationCenterListener.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNotificationCenterListener.m; sourceTree = "<group>"; };
508CE81522D12FF500357815 /* RNNotificationCenterListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNotificationCenterListener.h; sourceTree = "<group>"; };
508CE81722D130B900357815 /* RNPushKitEventListener.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNPushKitEventListener.h; sourceTree = "<group>"; };
508CE81822D130B900357815 /* RNPushKitEventListener.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNPushKitEventListener.m; sourceTree = "<group>"; };
508CE81B22D1337200357815 /* RNPushKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNPushKit.h; sourceTree = "<group>"; };
508CE81C22D1337200357815 /* RNPushKit.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNPushKit.m; sourceTree = "<group>"; };
508CE82022D1372E00357815 /* RNNotificationUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNotificationUtils.h; sourceTree = "<group>"; };
508CE82122D1372E00357815 /* RNNotificationUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNotificationUtils.m; sourceTree = "<group>"; };
50AD1FC822D13ADB00E12362 /* RNPushKitEventHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNPushKitEventHandler.h; sourceTree = "<group>"; };
50AD1FC922D13ADB00E12362 /* RNPushKitEventHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNPushKitEventHandler.m; sourceTree = "<group>"; };
50E49F0522D1E4E0007160C1 /* RNNotificationsStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNotificationsStore.h; sourceTree = "<group>"; };
50E49F0622D1E4E0007160C1 /* RNNotificationsStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNotificationsStore.m; sourceTree = "<group>"; };
50FED76422D3E06500DDD516 /* RNNotificationCenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNotificationCenter.h; sourceTree = "<group>"; };
50FED76522D3E06500DDD516 /* RNNotificationCenter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNotificationCenter.m; sourceTree = "<group>"; };
50FED76C22D3EBA800DDD516 /* RNNotificationParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNotificationParser.h; sourceTree = "<group>"; };
50FED76D22D3EBA800DDD516 /* RNNotificationParser.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNotificationParser.m; sourceTree = "<group>"; };
D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNotifications.m; sourceTree = "<group>"; };
D8A2F7561CB57F28002CC8F5 /* RNNotifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNotifications.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
508CE7C522D12B2600357815 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
508CE7CD22D12B2600357815 /* libRNNotifications.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
58B511D81A9E6C8500147676 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
......@@ -50,24 +125,134 @@
name = Products;
sourceTree = "<group>";
};
508CE7C922D12B2600357815 /* RNNotificationsTests */ = {
isa = PBXGroup;
children = (
508CE7CA22D12B2600357815 /* RNNotificationsTests.m */,
508CE7CC22D12B2600357815 /* Info.plist */,
);
path = RNNotificationsTests;
sourceTree = "<group>";
};
508CE81122D12F3C00357815 /* Notifications */ = {
isa = PBXGroup;
children = (
50FED76422D3E06500DDD516 /* RNNotificationCenter.h */,
50FED76522D3E06500DDD516 /* RNNotificationCenter.m */,
50E49F0522D1E4E0007160C1 /* RNNotificationsStore.h */,
50E49F0622D1E4E0007160C1 /* RNNotificationsStore.m */,
508CE7D322D12CCA00357815 /* RNNotificationEventHandler.h */,
508CE7D422D12CCA00357815 /* RNNotificationEventHandler.m */,
508CE81522D12FF500357815 /* RNNotificationCenterListener.h */,
508CE81322D12FC600357815 /* RNNotificationCenterListener.m */,
50FED76C22D3EBA800DDD516 /* RNNotificationParser.h */,
50FED76D22D3EBA800DDD516 /* RNNotificationParser.m */,
);
name = Notifications;
sourceTree = "<group>";
};
508CE81222D12F4300357815 /* PushKitNotifications */ = {
isa = PBXGroup;
children = (
508CE81B22D1337200357815 /* RNPushKit.h */,
508CE81C22D1337200357815 /* RNPushKit.m */,
508CE81722D130B900357815 /* RNPushKitEventListener.h */,
508CE81822D130B900357815 /* RNPushKitEventListener.m */,
50AD1FC822D13ADB00E12362 /* RNPushKitEventHandler.h */,
50AD1FC922D13ADB00E12362 /* RNPushKitEventHandler.m */,
);
name = PushKitNotifications;
sourceTree = "<group>";
};
508CE81F22D1371700357815 /* Helpers */ = {
isa = PBXGroup;
children = (
508CE82022D1372E00357815 /* RNNotificationUtils.h */,
508CE82122D1372E00357815 /* RNNotificationUtils.m */,
50351F9322CD7FF1000713B3 /* RCTConvert+RNNotifications.h */,
50351F9422CD7FF1000713B3 /* RCTConvert+RNNotifications.m */,
);
name = Helpers;
sourceTree = "<group>";
};
50E4A03D22D220E8007160C1 /* Bridge */ = {
isa = PBXGroup;
children = (
50351F9022CD7DF4000713B3 /* RNBridgeModule.h */,
50351F9122CD7DF4000713B3 /* RNBridgeModule.m */,
50351F8D22CD782F000713B3 /* RNEventEmitter.h */,
50351F8E22CD782F000713B3 /* RNEventEmitter.m */,
);
name = Bridge;
sourceTree = "<group>";
};
58B511D21A9E6C8500147676 = {
isa = PBXGroup;
children = (
D85B37461CC05A1200DE9EB6 /* RNNotificationsBridgeQueue.h */,
D85B37441CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m */,
50E4A03D22D220E8007160C1 /* Bridge */,
508CE81222D12F4300357815 /* PushKitNotifications */,
508CE81122D12F3C00357815 /* Notifications */,
508CE81F22D1371700357815 /* Helpers */,
D8A2F7561CB57F28002CC8F5 /* RNNotifications.h */,
D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */,
50351F9622CD8604000713B3 /* RNCommandsHandler.h */,
50351F9722CD8604000713B3 /* RNCommandsHandler.m */,
508CE7C922D12B2600357815 /* RNNotificationsTests */,
134814211AA4EA7D00B7C361 /* Products */,
508CE7C822D12B2600357815 /* RNNotificationsTests.xctest */,
);
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
507DCCF622CE3EEF005D4E0B /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
508CE81D22D1337200357815 /* RNPushKit.h in Headers */,
50AD1FCA22D13ADB00E12362 /* RNPushKitEventHandler.h in Headers */,
507DCCF922CE3F04005D4E0B /* RNNotifications.h in Headers */,
508CE7D522D12CCA00357815 /* RNNotificationEventHandler.h in Headers */,
50FED76622D3E06500DDD516 /* RNNotificationCenter.h in Headers */,
508CE81922D130B900357815 /* RNPushKitEventListener.h in Headers */,
50E49F0722D1E4E0007160C1 /* RNNotificationsStore.h in Headers */,
508CE81622D12FF600357815 /* RNNotificationCenterListener.h in Headers */,
508CE82222D1372E00357815 /* RNNotificationUtils.h in Headers */,
50FED76E22D3EBA800DDD516 /* RNNotificationParser.h in Headers */,
507DCCFA22CE3F04005D4E0B /* RNEventEmitter.h in Headers */,
507DCCFB22CE3F04005D4E0B /* RNCommandsHandler.h in Headers */,
507DCCFC22CE3F04005D4E0B /* RCTConvert+RNNotifications.h in Headers */,
507DCCF722CE3EF7005D4E0B /* RNBridgeModule.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
508CE7C722D12B2600357815 /* RNNotificationsTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 508CE7D022D12B2600357815 /* Build configuration list for PBXNativeTarget "RNNotificationsTests" */;
buildPhases = (
508CE7C422D12B2600357815 /* Sources */,
508CE7C522D12B2600357815 /* Frameworks */,
508CE7C622D12B2600357815 /* Resources */,
);
buildRules = (
);
dependencies = (
508CE7CF22D12B2600357815 /* PBXTargetDependency */,
);
name = RNNotificationsTests;
productName = RNNotificationsTests;
productReference = 508CE7C822D12B2600357815 /* RNNotificationsTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
58B511DA1A9E6C8500147676 /* RNNotifications */ = {
isa = PBXNativeTarget;
buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNNotifications" */;
buildPhases = (
507DCCF622CE3EEF005D4E0B /* Headers */,
58B511D71A9E6C8500147676 /* Sources */,
58B511D81A9E6C8500147676 /* Frameworks */,
58B511D91A9E6C8500147676 /* CopyFiles */,
......@@ -90,6 +275,10 @@
LastUpgradeCheck = 0610;
ORGANIZATIONNAME = Facebook;
TargetAttributes = {
508CE7C722D12B2600357815 = {
CreatedOnToolsVersion = 10.1;
ProvisioningStyle = Automatic;
};
58B511DA1A9E6C8500147676 = {
CreatedOnToolsVersion = 6.1.1;
};
......@@ -108,23 +297,133 @@
projectRoot = "";
targets = (
58B511DA1A9E6C8500147676 /* RNNotifications */,
508CE7C722D12B2600357815 /* RNNotificationsTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
508CE7C622D12B2600357815 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
508CE7C422D12B2600357815 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
508CE7CB22D12B2600357815 /* RNNotificationsTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
58B511D71A9E6C8500147676 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
50351F9822CD8604000713B3 /* RNCommandsHandler.m in Sources */,
D8A2F7551CB57F1A002CC8F5 /* RNNotifications.m in Sources */,
D85B37451CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m in Sources */,
50351F8F22CD782F000713B3 /* RNEventEmitter.m in Sources */,
508CE81A22D130B900357815 /* RNPushKitEventListener.m in Sources */,
50351F9222CD7DF4000713B3 /* RNBridgeModule.m in Sources */,
50FED76722D3E06500DDD516 /* RNNotificationCenter.m in Sources */,
50FED76F22D3EBA800DDD516 /* RNNotificationParser.m in Sources */,
508CE81E22D1337200357815 /* RNPushKit.m in Sources */,
508CE7D622D12CCA00357815 /* RNNotificationEventHandler.m in Sources */,
50E49F0822D1E4E0007160C1 /* RNNotificationsStore.m in Sources */,
508CE82322D1372E00357815 /* RNNotificationUtils.m in Sources */,
50351F9522CD7FF1000713B3 /* RCTConvert+RNNotifications.m in Sources */,
50AD1FCB22D13ADB00E12362 /* RNPushKitEventHandler.m in Sources */,
508CE81422D12FC700357815 /* RNNotificationCenterListener.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
508CE7CF22D12B2600357815 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 58B511DA1A9E6C8500147676 /* RNNotifications */;
targetProxy = 508CE7CE22D12B2600357815 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
508CE7D122D12B2600357815 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = RNNotificationsTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "";
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
508CE7D222D12B2600357815 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = RNNotificationsTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "";
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
58B511ED1A9E6C8500147676 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
......@@ -234,6 +533,15 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
508CE7D022D12B2600357815 /* Build configuration list for PBXNativeTarget "RNNotificationsTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
508CE7D122D12B2600357815 /* Debug */,
508CE7D222D12B2600357815 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNNotifications" */ = {
isa = XCConfigurationList;
buildConfigurations = (
......
#import <Foundation/Foundation.h>
@interface RNNotificationsBridgeQueue : NSObject
@property BOOL jsIsReady;
@property NSDictionary* openedRemoteNotification;
@property NSDictionary* openedLocalNotification;
+ (nonnull instancetype)sharedInstance;
- (void)postAction:(NSDictionary *)action withCompletionKey:(NSString *)completionKey andCompletionHandler:(void (^)())completionHandler;
- (void)postNotification:(NSDictionary *)notification;
- (void)consumeActionsQueue:(void (^)(NSDictionary *))block;
- (void)consumeNotificationsQueue:(void (^)(NSDictionary *))block;
- (void)completeAction:(NSString *)completionKey;
@end
\ No newline at end of file
#import "RNNotificationsBridgeQueue.h"
@implementation RNNotificationsBridgeQueue
NSMutableArray<NSDictionary *>* actionsQueue;
NSMutableArray<NSDictionary *>* notificationsQueue;
NSMutableDictionary* actionCompletionHandlers;
+ (nonnull instancetype)sharedInstance {
static RNNotificationsBridgeQueue* sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [self new];
});
return sharedInstance;
}
- (instancetype)init
{
actionsQueue = [NSMutableArray new];
notificationsQueue = [NSMutableArray new];
actionCompletionHandlers = [NSMutableDictionary new];
self.jsIsReady = NO;
return self;
}
- (void)postNotification:(NSDictionary *)notification
{
if (!notificationsQueue) return;
[notificationsQueue insertObject:notification atIndex:0];
}
- (NSDictionary *)dequeueSingleNotification
{
if (!notificationsQueue || notificationsQueue.count == 0) return nil;
NSDictionary* notification = [notificationsQueue lastObject];
[notificationsQueue removeLastObject];
return notification;
}
- (void)consumeNotificationsQueue:(void (^)(NSDictionary *))block
{
NSDictionary* notification;
while ((notification = [self dequeueSingleNotification]) != nil) {
block(notification);
}
notificationsQueue = nil;
}
- (void)postAction:(NSDictionary *)action withCompletionKey:(NSString *)completionKey andCompletionHandler:(void (^)())completionHandler
{
// store completion handler
actionCompletionHandlers[completionKey] = completionHandler;
if (!actionsQueue) return;
[actionsQueue insertObject:action atIndex:0];
}
- (NSDictionary *)dequeueSingleAction
{
if (!actionsQueue || actionsQueue.count == 0) return nil;
NSDictionary* action = [actionsQueue lastObject];
[actionsQueue removeLastObject];
return action;
}
- (void)consumeActionsQueue:(void (^)(NSDictionary *))block
{
NSDictionary* lastActionInfo;
while ((lastActionInfo = [self dequeueSingleAction]) != nil) {
block(lastActionInfo);
}
actionsQueue = nil;
}
- (void)completeAction:(NSString *)completionKey
{
void (^completionHandler)() = (void (^)())[actionCompletionHandlers valueForKey:completionKey];
if (completionHandler) {
completionHandler();
[actionCompletionHandlers removeObjectForKey:completionKey];
}
}
@end
\ No newline at end of file
#import <Foundation/Foundation.h>
@import UserNotifications;
@interface RNNotificationsStore : NSObject
@property (nonatomic, retain) NSDictionary* initialNotification;
+ (instancetype)sharedInstance;
- (void)completeAction:(NSString *)completionKey;
- (void)completePresentation:(NSString *)completionKey withPresentationOptions:(UNNotificationPresentationOptions)presentationOptions;
- (void)setActionCompletionHandler:(void (^)())completionHandler withCompletionKey:(NSString *)completionKey;
- (void)setPresentationCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler withCompletionKey:(NSString *)completionKey;
@end
#import "RNNotificationsStore.h"
@implementation RNNotificationsStore
NSMutableDictionary* _actionCompletionHandlers;
NSMutableDictionary* _presentationCompletionHandlers;
+ (instancetype)sharedInstance {
static RNNotificationsStore *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[RNNotificationsStore alloc] init];
});
return sharedInstance;
}
- (instancetype)init {
self = [super init];
_actionCompletionHandlers = [NSMutableDictionary new];
_presentationCompletionHandlers = [NSMutableDictionary new];
return self;
}
- (void)setActionCompletionHandler:(void (^)())completionHandler withCompletionKey:(NSString *)completionKey {
_actionCompletionHandlers[completionKey] = completionHandler;
}
- (void)setPresentationCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler withCompletionKey:(NSString *)completionKey {
_presentationCompletionHandlers[completionKey] = completionHandler;
}
- (void)completeAction:(NSString *)completionKey {
void (^completionHandler)() = (void (^)())[_actionCompletionHandlers valueForKey:completionKey];
if (completionHandler) {
completionHandler();
[_actionCompletionHandlers removeObjectForKey:completionKey];
}
}
- (void)completePresentation:(NSString *)completionKey withPresentationOptions:(UNNotificationPresentationOptions)presentationOptions {
void (^completionHandler)() = (void (^)(UNNotificationPresentationOptions))[_presentationCompletionHandlers valueForKey:completionKey];
if (completionHandler) {
completionHandler(presentationOptions);
[_actionCompletionHandlers removeObjectForKey:completionKey];
}
}
@end
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
//
// RNNotificationsTests.m
// RNNotificationsTests
//
// Created by Yogev Ben David on 06/07/2019.
// Copyright © 2019 Facebook. All rights reserved.
//
#import <XCTest/XCTest.h>
@interface RNNotificationsTests : XCTestCase
@end
@implementation RNNotificationsTests
- (void)setUp {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
- (void)testExample {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
- (void)testPerformanceExample {
// This is an example of a performance test case.
[self measureBlock:^{
// Put the code you want to measure the time of here.
}];
}
@end
#import <UIKit/UIKit.h>
#import "RNPushKitEventListener.h"
@import PushKit;
@interface RNPushKit : NSObject
- (instancetype)initWithEventHandler:(RNPushKitEventHandler *)pushKitEventHandler;
@end
#import "RNPushKit.h"
@implementation RNPushKit {
RNPushKitEventListener* _pushKitEventListener;
}
- (instancetype)initWithEventHandler:(RNPushKitEventHandler *)pushKitEventHandler {
self = [super init];
_pushKitEventListener = [[RNPushKitEventListener alloc] initWithPushKitEventHandler:pushKitEventHandler];
PKPushRegistry* pushKitRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushKitRegistry.delegate = _pushKitEventListener;
pushKitRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
return self;
}
@end
#import <Foundation/Foundation.h>
#import "RNNotificationEventHandler.h"
@interface RNPushKitEventHandler : RNNotificationEventHandler
- (void)registeredWithToken:(NSString *)token;
- (void)didReceiveIncomingPushWithPayload:(NSDictionary *)payload;
@end
#import "RNPushKitEventHandler.h"
#import "RNEventEmitter.h"
@implementation RNPushKitEventHandler
- (void)registeredWithToken:(NSString *)token {
[RNEventEmitter sendEvent:RNPushKitRegistered body:@{@"pushKitToken": token}];
}
- (void)didReceiveIncomingPushWithPayload:(NSDictionary *)payload {
[RNEventEmitter sendEvent:RNPushKitNotificationReceived body:payload];
}
@end
#import <Foundation/Foundation.h>
@import PushKit;
#import "RNPushKitEventHandler.h"
@interface RNPushKitEventListener : NSObject <PKPushRegistryDelegate>
- (instancetype)initWithPushKitEventHandler:(RNPushKitEventHandler *)pushKitEventHandler;
@end
#import "RNPushKitEventListener.h"
#import "RNNotificationUtils.h"
@implementation RNPushKitEventListener {
PKPushRegistry* _pushRegistry;
RNPushKitEventHandler* _pushKitEventHandler;
}
- (instancetype)initWithPushKitEventHandler:(RNPushKitEventHandler *)pushKitEventHandler {
self = [super init];
_pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
_pushKitEventHandler = pushKitEventHandler;
return self;
}
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {
[_pushKitEventHandler registeredWithToken:[RNNotificationUtils deviceTokenToString:credentials.token]];
}
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
[_pushKitEventHandler didReceiveIncomingPushWithPayload:payload.dictionaryPayload];
}
@end
module.exports = function (api) {
api && api.cache(false);
return {
presets: [
'module:metro-react-native-babel-preset'
],
plugins: [
'@babel/plugin-proposal-export-namespace-from',
'@babel/plugin-proposal-export-default-from'
]
};
};
......@@ -91,33 +91,31 @@ After [preparing your app to receive VoIP push notifications](https://developer.
#import <PushKit/PushKit.h>
```
And the following methods:
### Listen to PushKit notifications
On receiving PushKit notification, a `pushKitNotificationReceived` event will be fired with the notification payload.
```objective-c
// PushKit API Support
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type
{
[RNNotifications didUpdatePushCredentials:credentials forType:type];
}
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
{
[RNNotifications didReceiveRemoteNotification:payload.dictionaryPayload];
}
```
#import "RNNotifications.h"
#import <PushKit/PushKit.h>
```
In your ReactNative code, add event handler for `pushKitRegistered` event and call to `registerPushKit()`:
```javascript
constructor() {
NotificationsIOS.addEventListener('pushKitRegistered', this.onPushKitRegistered.bind(this));
NotificationsIOS.registerPushKit();
NotificationsIOS.addEventListener('pushKitRegistered', this.onPushKitRegistered.bind(this));
NotificationsIOS.addEventListener('pushKitNotificationReceived', this.onPushKitNotificationReceived.bind(this));
NotificationsIOS.registerPushKit();
}
onPushKitRegistered(deviceToken) {
console.log("PushKit Token Received: " + deviceToken);
}
onPushKitNotificationReceived(notification) {
console.log('PushKit notification Received: ' + JSON.stringify(notification));
}
componentWillUnmount() {
// Don't forget to remove the event listeners to prevent memory leaks!
NotificationsIOS.removeEventListener('pushKitRegistered', onPushKitRegistered(this));
......@@ -150,22 +148,7 @@ Notification **actions** allow the user to interact with a given notification.
Notification **categories** allow you to group multiple actions together, and to connect the actions with the push notification itself.
In order to support interactive notifications, firstly add the following methods to `appDelegate.m` file:
```objective-c
// Required for the notification actions.
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler
{
[RNNotifications handleActionWithIdentifier:identifier forLocalNotification:notification withResponseInfo:responseInfo completionHandler:completionHandler];
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler
{
[RNNotifications handleActionWithIdentifier:identifier forRemoteNotification:userInfo withResponseInfo:responseInfo completionHandler:completionHandler];
}
```
Then, follow the basic workflow of adding interactive notifications to your app:
Follow the basic workflow of adding interactive notifications to your app:
1. Config the actions.
2. Group actions together into categories.
......@@ -182,26 +165,18 @@ import NotificationsIOS, { NotificationAction, NotificationCategory } from 'reac
let upvoteAction = new NotificationAction({
activationMode: "background",
title: String.fromCodePoint(0x1F44D),
identifier: "UPVOTE_ACTION"
}, (action, completed) => {
console.log("ACTION RECEIVED");
console.log(JSON.stringify(action));
// You must call to completed(), otherwise the action will not be triggered
completed();
identifier: "UPVOTE_ACTION",
textInput: {
buttonTitle: 'title',
placeholder: 'placeholder text'
}
});
let replyAction = new NotificationAction({
activationMode: "background",
title: "Reply",
behavior: "textInput",
authenticationRequired: true,
identifier: "REPLY_ACTION"
}, (action, completed) => {
console.log("ACTION RECEIVED");
console.log(action);
completed();
});
```
......@@ -212,8 +187,7 @@ We will group `upvote` action and `reply` action into a single category: `EXAMPL
```javascript
let exampleCategory = new NotificationCategory({
identifier: "EXAMPLE_CATEGORY",
actions: [upvoteAction, replyAction],
context: "default"
actions: [upvoteAction, replyAction]
});
```
......@@ -230,8 +204,8 @@ Notification payload should look like this:
```javascript
{
aps: {
// ... (alert, sound, badge, etc)
category: "EXAMPLE_CATEGORY"
// ... (alert, sound, badge, etc)
category: "EXAMPLE_CATEGORY"
}
}
```
......@@ -245,9 +219,7 @@ The [example app](https://github.com/wix/react-native-notifications/tree/master/
- `activationMode` - Indicating whether the app should activate to the foreground or background.
- `foreground` (default) - Activate the app and put it in the foreground.
- `background` - Activate the app and put it in the background. If the app is already in the foreground, it remains in the foreground.
- `behavior` - Indicating additional behavior that the action supports.
- `default` - No additional behavior.
- `textInput` - When button is tapped, the action opens a text input. the text will be delivered to your action callback.
- `textInput` - `TextInput` payload, when supplied, the system will present text input in this action.
- `destructive` - A Boolean value indicating whether the action is destructive. When the value of this property is `true`, the system displays the corresponding button differently to indicate that the action is destructive.
- `authenticationRequired` - A Boolean value indicating whether the user must unlock the device before the action is performed.
......@@ -255,9 +227,11 @@ The [example app](https://github.com/wix/react-native-notifications/tree/master/
- `identifier` - The name of the action group (must be unique).
- `actions` - An array of `NotificationAction` objects, which related to this category.
- `context` - Indicating the amount of space available for displaying actions in a notification.
- `default` (default) - Displayes up to 4 actions (full UI).
- `minimal` - Displays up tp 2 actions (minimal UI).
### `TextInput` Payload
- `buttonTitle` - Title of the `send` button.
- `placeholder` - Placeholder for the `textInput`.
#### Get and set application icon badges count (iOS only)
......
......@@ -20,17 +20,24 @@ Then, to enable notifications support add the following line at the top of your
#import "RNNotifications.h"
```
And the following methods to support registration and receiving notifications:
Start monitor notifications in: `application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions`
```objective-c
// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
[RNNotifications didRegisterUserNotificationSettings:notificationSettings];
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[RNNotifications startMonitorNotifications]; // -> Add this line
return YES;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
```
And add the following methods to support registration:
```objective-c
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[RNNotifications didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
......@@ -38,16 +45,6 @@ And the following methods to support registration and receiving notifications:
[RNNotifications didFailToRegisterForRemoteNotificationsWithError:error];
}
// Required for the notification event.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification {
[RNNotifications didReceiveRemoteNotification:notification];
}
// Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
[RNNotifications didReceiveLocalNotification:notification];
}
```
## <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/APK_format_icon.png/768px-APK_format_icon.png" width=30/> Android
......
......@@ -10,9 +10,9 @@ Example:
```javascript
let localNotification = NotificationsIOS.localNotification({
alertBody: "Local notificiation!",
alertTitle: "Local Notification Title",
soundName: "chime.aiff",
body: "Local notificiation!",
title: "Local Notification Title",
sound: "chime.aiff",
silent: false,
category: "SOME_CATEGORY",
userInfo: { }
......@@ -22,10 +22,10 @@ let localNotification = NotificationsIOS.localNotification({
Notification object contains:
- **`fireDate`**- The date and time when the system should deliver the notification (optinal - default is immidiate dispatch).
- `alertBody`- The message displayed in the notification alert.
- `alertTitle`- The title of the notification, displayed in the notifications center.
- `body`- The message displayed in the notification alert.
- `title`- The title of the notification, displayed in the notifications center.
- `alertAction`- The "action" displayed beneath an actionable notification on the lockscreen (e.g. "Slide to **open**"). Note that Apple no longer shows this in iOS 10.
- `soundName`- The sound played when the notification is fired (optional -- will play default sound if unspecified). This must be the filename of a sound included in the application bundle; the sound must be 30 seconds or less and should be encoded with linear PCM or IMA4.
- `sound`- The sound played when the notification is fired (optional -- will play default sound if unspecified). This must be the filename of a sound included in the application bundle; the sound must be 30 seconds or less and should be encoded with linear PCM or IMA4.
- `silent`- Whether the notification sound should be suppressed (optional).
- `category`- The category of this notification, required for [interactive notifications](#interactive--actionable-notifications-ios-only) (optional).
- `userInfo`- An optional object containing additional notification data.
......@@ -38,9 +38,9 @@ Example:
```javascript
let someLocalNotification = NotificationsIOS.localNotification({
alertBody: "Local notificiation!",
alertTitle: "Local Notification Title",
soundName: "chime.aiff",
body: "Local notificiation!",
title: "Local Notification Title",
sound: "chime.aiff",
category: "SOME_CATEGORY",
userInfo: { }
});
......
......@@ -5,40 +5,35 @@
When a push notification is received by the device, the application can be in one of the following states:
1. **Forground:** When the app is running and is used by the user right now; in this case, a `notificationReceivedForeground` event will be fired.
2. **Background:** When the app is running in a background state; in this case, a `notificationReceivedBackground` event will be fired.
1. **Forground:** When the app is running and is used by the user right now; in this case, a `notificationReceivedForeground` event will be fired, do not forget to invoke `completion()` callback.
Finally, when a notification is _opened_ by the device user (i.e. tapped-on), a `notificationOpened` event is fired.
Finally, when a notification is _opened_ by the device user (i.e. tapped-on), a `notificationOpened` event is fired, here as well you need to remember invoking `completion()` callback.
Example:
```javascript
constructor() {
this._boundOnNotificationReceivedForeground = this.onNotificationReceivedForeground.bind(this);
this._boundOnNotificationReceivedBackground = this.onNotificationReceivedBackground.bind(this);
this._boundOnNotificationOpened = this.onNotificationOpened.bind(this);
NotificationsIOS.addEventListener('notificationReceivedForeground', this._boundOnNotificationReceivedForeground);
NotificationsIOS.addEventListener('notificationReceivedBackground', this._boundOnNotificationReceivedBackground);
NotificationsIOS.addEventListener('notificationOpened', this._boundOnNotificationOpened);
}
onNotificationReceivedForeground(notification) {
onNotificationReceivedForeground(notification, completion) {
completion({alert: true, sound: false, badge: false});
console.log("Notification Received - Foreground", notification);
}
onNotificationReceivedBackground(notification) {
console.log("Notification Received - Background", notification);
}
onNotificationOpened(notification) {
onNotificationOpened(notification, completion, action) {
console.log("Notification opened by device user", notification);
console.log(`Notification opened with an action identifier: ${action.identifier} and response text: ${action.text}`, notification);
completion();
}
componentWillUnmount() {
// Don't forget to remove the event listeners to prevent memory leaks!
NotificationsIOS.removeEventListener('notificationReceivedForeground', this._boundOnNotificationReceivedForeground);
NotificationsIOS.removeEventListener('notificationReceivedBackground', this._boundOnNotificationReceivedBackground);
NotificationsIOS.removeEventListener('notificationOpened', this._boundOnNotificationOpened);
}
```
......@@ -54,12 +49,6 @@ When you receive a push notification, you'll get an instance of `IOSNotification
- **`getData()`**- returns the data payload (additional info) of the notification.
- **`getType()`**- returns `managed` for managed notifications, otherwise returns `regular`.
### Background Queue (Important - please read!)
When a push notification is opened but the app is not running, the application will be in a **cold launch** state, until the JS engine is up and ready to handle the notification.
The application will collect the events (notifications, actions, etc.) that happend during the cold launch for you.
When your app is ready (most of the time it's after the call to `requestPermissions()`), just call to `NotificationsIOS.consumeBackgroundQueue();` in order to consume the background queue. For more info see `index.ios.js` in the example app.
## <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/APK_format_icon.png/768px-APK_format_icon.png" width=30/> Android
......
const Utils = require('./Utils');
const { elementByLabel } = Utils;
describe('Notifications', () => {
describe('Foreground', () => {
beforeEach(async () => {
await device.relaunchApp({permissions: {notifications: 'YES'}});
});
it('Receive notification', async () => {
await device.sendUserNotification(createNotification({link: 'foreground/notification'}));
await expect(elementByLabel('foreground/notification')).toBeVisible();
});
it('Click notification', async () => {
await device.sendUserNotification(createNotification({link: 'foreground/notification/click', showAlert: true}));
await expect(elementByLabel('Notification Clicked: foreground/notification/click')).toBeVisible();
});
});
describe('Background', () => {
beforeEach(async () => {
await device.launchApp({newInstance: true, permissions: {notifications: 'YES'}});
});
it('Receive notification', async () => {
device.sendToHome();
await expect(elementByLabel('background/notification')).toBeNotVisible();
device.launchApp({newInstance: false, userNotification: createNotification({link: 'background/notification'})});
await expect(elementByLabel('background/notification')).toBeVisible();
});
});
describe('Dead state', () => {
it('Receive notification', async () => {
await device.launchApp({newInstance: true, userNotification: createNotification({link: 'deadState/notification'})});
await expect(elementByLabel('deadState/notification')).toBeVisible();
});
});
});
function createNotification({link, showAlert}) {
return {
trigger: {
type: 'push'
},
title: 'From push',
subtitle: 'Subtitle',
body: 'Body',
badge: 1,
payload: {
link,
showAlert
}
};
}
const exec = require('shell-utils').exec;
module.exports = {
elementByLabel: (label) => {
return element(by.text(label));
},
elementById: (id) => {
return element(by.id(id));
},
tapBackIos: () => {
try {
return element(by.traits(['button']).and(by.label('Back'))).atIndex(0).tap();
} catch (err) {
return element(by.type('_UIModernBarButton').and(by.label('Back'))).tap();
}
},
sleep: ms => new Promise(res => setTimeout(res, ms))
};
{
"setupTestFrameworkScriptFile" : "./init.js",
"testEnvironment": "node",
"bail": true,
"verbose": true
}
const detox = require('detox');
const config = require('../package.json').detox;
const exec = require('shell-utils').exec;
const adapter = require('detox/runners/jest/adapter');
jest.setTimeout(300000);
jasmine.getEnv().addReporter(adapter);
beforeAll(async () => {
await detox.init(config, {launchApp: false});
disableAndroidEmulatorAnimations();
});
afterAll(async () => {
await adapter.afterAll();
await detox.cleanup();
});
beforeEach(async () => {
await adapter.beforeEach();
});
function disableAndroidEmulatorAnimations() {
if (device.getPlatform() === 'android') {
const deviceId = device._deviceId;
exec.execAsync(`adb -s ${deviceId} shell settings put global window_animation_scale 0.0`);
exec.execAsync(`adb -s ${deviceId} shell settings put global transition_animation_scale 0.0`);
exec.execAsync(`adb -s ${deviceId} shell settings put global animator_duration_scale 0.0`);
}
}
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
import {
AppRegistry,
StyleSheet,
View,
Text,
View
Button
} from 'react-native';
import React, {Component} from 'react';
import NotificationsIOS, { NotificationAction, NotificationCategory } from 'react-native-notifications';
let upvoteAction = new NotificationAction({
activationMode: "background",
activationMode: 'background',
title: String.fromCodePoint(0x1F44D),
identifier: "UPVOTE_ACTION"
}, (action, completed) => {
NotificationsIOS.log("ACTION RECEIVED");
NotificationsIOS.log(JSON.stringify(action));
completed();
identifier: 'UPVOTE_ACTION'
});
let replyAction = new NotificationAction({
activationMode: "background",
title: "Reply",
behavior: "textInput",
activationMode: 'background',
title: 'Reply',
authenticationRequired: true,
identifier: "REPLY_ACTION"
}, (action, completed) => {
console.log("ACTION RECEIVED");
console.log(action);
completed();
});
let cat = new NotificationCategory({
identifier: "SOME_CATEGORY",
actions: [upvoteAction, replyAction],
context: "default"
textInput: {
buttonTitle: 'Reply now',
placeholder: 'Insert message'
},
identifier: 'REPLY_ACTION'
});
class NotificationsExampleApp extends Component {
constructor() {
super();
NotificationsIOS.addEventListener('remoteNotificationsRegistered', this.onPushRegistered.bind(this));
NotificationsIOS.requestPermissions([cat]);
this.state = {
notifications: []
};
NotificationsIOS.consumeBackgroundQueue();
NotificationsIOS.addEventListener('remoteNotificationsRegistered', this.onPushRegistered.bind(this));
NotificationsIOS.addEventListener('remoteNotificationsRegistrationFailed', this.onPushRegisteredFailed.bind(this));
NotificationsIOS.addEventListener('pushKitRegistered', this.onPushKitRegistered.bind(this));
NotificationsIOS.registerPushKit();
NotificationsIOS.addEventListener('notificationReceivedForeground', this.onNotificationReceivedForeground.bind(this));
NotificationsIOS.addEventListener('notificationReceivedBackground', this.onNotificationReceivedBackground.bind(this));
NotificationsIOS.addEventListener('notificationOpened', this.onNotificationOpened.bind(this));
NotificationsIOS.addEventListener('pushKitNotificationReceived', this.onPushKitNotificationReceived.bind(this));
}
async componentDidMount() {
const initialNotification = await NotificationsIOS.getInitialNotification();
if (initialNotification) {
this.setState({notifications: [initialNotification.getData().link, ...this.state.notifications]});
}
}
onPushRegistered(deviceToken) {
console.log("Device Token Received: " + deviceToken);
console.log('Device Token Received: ' + deviceToken);
}
onPushKitRegistered(deviceToken) {
console.log("PushKit Token Received: " + deviceToken);
onPushRegisteredFailed(error) {
console.log('Remote notifiction registration failed: ' + error);
}
onNotificationReceivedForeground(notification) {
console.log("Notification Received Foreground: " + JSON.stringify(notification));
onPushKitRegistered(deviceToken) {
console.log('PushKit Token Received: ' + deviceToken);
}
onNotificationReceivedBackground(notification) {
NotificationsIOS.log("Notification Received Background: " + JSON.stringify(notification));
onPushKitNotificationReceived(notification) {
console.log('PushKit notification Received: ' + JSON.stringify(notification));
}
let localNotification = NotificationsIOS.localNotification({
alertBody: "Received background notificiation!",
alertTitle: "Local Notification Title",
alertAction: "Click here to open",
soundName: "chime.aiff",
category: "SOME_CATEGORY",
userInfo: notification.getData()
onNotificationReceivedForeground(notification, completion) {
console.log('Notification Received Foreground with title: ' + JSON.stringify(notification));
this.setState({
notifications: [...this.state.notifications, notification.getData().link]
});
// if you want to fire the local notification 10 seconds later,
// add the following line to the notification payload:
// fireDate: new Date(Date.now() + (10 * 1000)).toISOString()
// NotificationsIOS.backgroundTimeRemaining(time => NotificationsIOS.log("remaining background time: " + time));
completion({alert: notification.getData().showAlert, sound: false, badge: false});
}
// NotificationsIOS.cancelLocalNotification(localNotification);
onNotificationOpened(notification, completion, action) {
console.log('Notification Opened: ' + JSON.stringify(notification) + JSON.stringify(action));
this.setState({
notifications: [...this.state.notifications, `Notification Clicked: ${notification.getData().link}`]
});
completion();
}
onNotificationOpened(notification) {
console.log("Notification Opened: " + JSON.stringify(notification));
renderNotification(notification) {
return <Text>{`${notification}`}</Text>;
}
render() {
const notifications = this.state.notifications.map((notification, idx) =>
(
<View key={`notification_${idx}`}>
{this.renderNotification(notification)}
</View>
));
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native Notifications Demo App!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
</Text>
<Button title={'Request permissions'} onPress={this.requestPermissions} testID={'requestPermissions'}/>
<Button title={'Send local notification'} onPress={this.sendLocalNotification} testID={'sendLocalNotification'}/>
<Button title={'Remove all delivered notifications'} onPress={this.removeAllDeliveredNotifications}/>
{notifications}
</View>
);
}
requestPermissions() {
let cat = new NotificationCategory({
identifier: 'SOME_CATEGORY',
actions: [upvoteAction, replyAction]
});
NotificationsIOS.requestPermissions([cat]);
}
sendLocalNotification() {
NotificationsIOS.localNotification({
body: 'Local notificiation!',
title: 'Local Notification Title',
sound: 'chime.aiff',
category: 'SOME_CATEGORY',
userInfo: { }
});
}
removeAllDeliveredNotifications() {
NotificationsIOS.removeAllDeliveredNotifications();
}
componentWillUnmount() {
NotificationsIOS.removeEventListener('notificationReceivedForeground', this.onNotificationReceivedForeground.bind(this));
NotificationsIOS.removeEventListener('notificationReceivedBackground', this.onNotificationReceivedBackground.bind(this));
NotificationsIOS.removeEventListener('notificationOpened', this.onNotificationOpened.bind(this));
NotificationsIOS.removeEventListener('remoteNotificationsRegistered', this.onPushRegistered.bind(this));
NotificationsIOS.removeEventListener('pushKitRegistered', this.onPushKitRegistered.bind(this));
// NotificationsIOS.resetCategories();
}
_onNotification(notification) {
AlertIOS.alert(
'Notification Received',
'Alert message: ' + notification.getMessage(),
[{
text: 'Dismiss',
onPress: null,
}]
);
}
}
......
......@@ -7,255 +7,256 @@
objects = {
/* Begin PBXBuildFile section */
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; };
00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
50F1F0CC22CE3B4700FD5829 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F06022CE3A6100FD5829 /* libReact.a */; };
50F1F0CD22CE3B6300FD5829 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F08A22CE3AA000FD5829 /* libRCTActionSheet.a */; };
50F1F0CF22CE3B6300FD5829 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F09522CE3ABE00FD5829 /* libRCTImage.a */; };
50F1F0D022CE3B6300FD5829 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F09D22CE3ACA00FD5829 /* libRCTLinking.a */; };
50F1F0D122CE3B6300FD5829 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F0A622CE3B0600FD5829 /* libRCTNetwork.a */; };
50F1F0D222CE3B6300FD5829 /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F0AE22CE3B1000FD5829 /* libRCTSettings.a */; };
50F1F0D322CE3B6300FD5829 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F0B622CE3B1A00FD5829 /* libRCTText.a */; };
50F1F0D422CE3B6300FD5829 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F0BD22CE3B2400FD5829 /* libRCTVibration.a */; };
50F1F0D522CE3B6300FD5829 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F0C522CE3B2E00FD5829 /* libRCTWebSocket.a */; };
50F1F0D622CE3C0F00FD5829 /* libyoga.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F06422CE3A6100FD5829 /* libyoga.a */; };
50F1F0D722CE3C1E00FD5829 /* libcxxreact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F06822CE3A6100FD5829 /* libcxxreact.a */; };
D84861182267695100E9103D /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D84861172267695100E9103D /* JavaScriptCore.framework */; };
D85498D21D97B37F00DEEE06 /* libRNNotifications.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D85498D11D97B31100DEEE06 /* libRNNotifications.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = {
50E49F4022D1F06C007160C1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTActionSheet;
};
00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTGeolocation;
};
00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
remoteInfo = RCTImage;
remoteGlobalIDString = EDEBC6D6214B3E7000DD5AC8;
remoteInfo = jsi;
};
00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = {
50E49F4222D1F06C007160C1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 58B511DB1A9E6C8500147676;
remoteInfo = RCTNetwork;
remoteGlobalIDString = EDEBC73B214B45A300DD5AC8;
remoteInfo = jsiexecutor;
};
00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = {
50E49F4422D1F06C007160C1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 832C81801AAF6DEF007FA2F7;
remoteInfo = RCTVibration;
remoteGlobalIDString = ED296FB6214C9A0900B7C4FE;
remoteInfo = "jsi-tvOS";
};
139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = {
50E49F4622D1F06C007160C1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTSettings;
remoteGlobalIDString = ED296FEE214C9CF800B7C4FE;
remoteInfo = "jsiexecutor-tvOS";
};
139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = {
50E49F4A22D1F06C007160C1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
containerPortal = D85498C21D97B31100DEEE06 /* RNNotifications.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
remoteInfo = RCTWebSocket;
remoteGlobalIDString = 508CE7C822D12B2600357815;
remoteInfo = RNNotificationsTests;
};
146834031AC3E56700842450 /* PBXContainerItemProxy */ = {
50F1F05F22CE3A6100FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
remoteInfo = React;
};
18B5569B2007789B007ACD82 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3DBE0D001F3B181A0099AA32;
remoteInfo = fishhook;
};
18B5569D2007789B007ACD82 /* PBXContainerItemProxy */ = {
50F1F06122CE3A6100FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3DBE0D0D1F3B181C0099AA32;
remoteInfo = "fishhook-tvOS";
remoteGlobalIDString = 2D2A28131D9B038B00D4039D;
remoteInfo = "React-tvOS";
};
18B556AD2007789B007ACD82 /* PBXContainerItemProxy */ = {
50F1F06322CE3A6100FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3D3C059A1DE3340900C268FA;
remoteInfo = yoga;
};
18B556AF2007789B007ACD82 /* PBXContainerItemProxy */ = {
50F1F06522CE3A6100FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3D3C06751DE3340C00C268FA;
remoteInfo = "yoga-tvOS";
};
18B556B12007789B007ACD82 /* PBXContainerItemProxy */ = {
50F1F06722CE3A6100FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3D3CD9251DE5FBEC00167DC4;
remoteInfo = cxxreact;
};
18B556B32007789B007ACD82 /* PBXContainerItemProxy */ = {
50F1F06922CE3A6100FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3D3CD9321DE5FBEE00167DC4;
remoteInfo = "cxxreact-tvOS";
};
18B556B92007789B007ACD82 /* PBXContainerItemProxy */ = {
50F1F06F22CE3A6100FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = EBF21BDC1FC498900052F4D5;
remoteInfo = jsinspector;
};
50F1F07122CE3A6100FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = EBF21BFA1FC4989A0052F4D5;
remoteInfo = "jsinspector-tvOS";
};
50F1F07322CE3A6100FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 139D7ECE1E25DB7D00323FB7;
remoteInfo = "third-party";
};
18B556BB2007789B007ACD82 /* PBXContainerItemProxy */ = {
50F1F07522CE3A6100FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3D383D3C1EBD27B6005632C8;
remoteInfo = "third-party-tvOS";
};
18B556BD2007789B007ACD82 /* PBXContainerItemProxy */ = {
50F1F07722CE3A6100FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 139D7E881E25C6D100323FB7;
remoteInfo = "double-conversion";
};
18B556BF2007789B007ACD82 /* PBXContainerItemProxy */ = {
50F1F07922CE3A6100FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3D383D621EBD27B9005632C8;
remoteInfo = "double-conversion-tvOS";
};
18BA9BF01DEC2288001F416D /* PBXContainerItemProxy */ = {
50F1F08922CE3AA000FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
containerPortal = 50F1F08522CE3A9F00FD5829 /* RCTActionSheet.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 2D2A283A1D9B042B00D4039D;
remoteInfo = "RCTImage-tvOS";
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTActionSheet;
};
18BA9BF41DEC2288001F416D /* PBXContainerItemProxy */ = {
50F1F09422CE3ABE00FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 2D2A28471D9B043800D4039D;
remoteInfo = "RCTLinking-tvOS";
remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
remoteInfo = RCTImage;
};
18BA9BF81DEC2288001F416D /* PBXContainerItemProxy */ = {
50F1F09622CE3ABE00FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 2D2A28541D9B044C00D4039D;
remoteInfo = "RCTNetwork-tvOS";
remoteGlobalIDString = 2D2A283A1D9B042B00D4039D;
remoteInfo = "RCTImage-tvOS";
};
18BA9BFC1DEC2288001F416D /* PBXContainerItemProxy */ = {
50F1F09C22CE3ACA00FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 2D2A28611D9B046600D4039D;
remoteInfo = "RCTSettings-tvOS";
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTLinking;
};
18BA9C001DEC2288001F416D /* PBXContainerItemProxy */ = {
50F1F09E22CE3ACA00FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 2D2A287B1D9B048500D4039D;
remoteInfo = "RCTText-tvOS";
remoteGlobalIDString = 2D2A28471D9B043800D4039D;
remoteInfo = "RCTLinking-tvOS";
};
18BA9C051DEC2288001F416D /* PBXContainerItemProxy */ = {
50F1F0A522CE3B0600FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
containerPortal = 50F1F0A022CE3B0600FD5829 /* RCTNetwork.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 2D2A28881D9B049200D4039D;
remoteInfo = "RCTWebSocket-tvOS";
remoteGlobalIDString = 58B511DB1A9E6C8500147676;
remoteInfo = RCTNetwork;
};
18BA9C091DEC2288001F416D /* PBXContainerItemProxy */ = {
50F1F0A722CE3B0600FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
containerPortal = 50F1F0A022CE3B0600FD5829 /* RCTNetwork.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 2D2A28131D9B038B00D4039D;
remoteInfo = "React-tvOS";
remoteGlobalIDString = 2D2A28541D9B044C00D4039D;
remoteInfo = "RCTNetwork-tvOS";
};
78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {
50F1F0AD22CE3B1000FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTLinking;
remoteInfo = RCTSettings;
};
832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
50F1F0AF22CE3B1000FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 2D2A28611D9B046600D4039D;
remoteInfo = "RCTSettings-tvOS";
};
50F1F0B522CE3B1A00FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
remoteInfo = RCTText;
};
D848610A2267695100E9103D /* PBXContainerItemProxy */ = {
50F1F0B722CE3B1A00FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = EBF21BDC1FC498900052F4D5;
remoteInfo = jsinspector;
remoteGlobalIDString = 2D2A287B1D9B048500D4039D;
remoteInfo = "RCTText-tvOS";
};
D848610C2267695100E9103D /* PBXContainerItemProxy */ = {
50F1F0BC22CE3B2400FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = EBF21BFA1FC4989A0052F4D5;
remoteInfo = "jsinspector-tvOS";
remoteGlobalIDString = 832C81801AAF6DEF007FA2F7;
remoteInfo = RCTVibration;
};
D848610E2267695100E9103D /* PBXContainerItemProxy */ = {
50F1F0C422CE3B2E00FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = EDEBC6D6214B3E7000DD5AC8;
remoteInfo = jsi;
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
remoteInfo = RCTWebSocket;
};
D84861102267695100E9103D /* PBXContainerItemProxy */ = {
50F1F0C622CE3B2E00FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = EDEBC73B214B45A300DD5AC8;
remoteInfo = jsiexecutor;
remoteGlobalIDString = 2D2A28881D9B049200D4039D;
remoteInfo = "RCTWebSocket-tvOS";
};
D84861122267695100E9103D /* PBXContainerItemProxy */ = {
50F1F0C822CE3B2E00FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = ED296FB6214C9A0900B7C4FE;
remoteInfo = "jsi-tvOS";
remoteGlobalIDString = 3DBE0D001F3B181A0099AA32;
remoteInfo = fishhook;
};
D84861142267695100E9103D /* PBXContainerItemProxy */ = {
50F1F0CA22CE3B2E00FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = ED296FEE214C9CF800B7C4FE;
remoteInfo = "jsiexecutor-tvOS";
remoteGlobalIDString = 3DBE0D0D1F3B181C0099AA32;
remoteInfo = "fishhook-tvOS";
};
D85498D01D97B31100DEEE06 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
......@@ -268,15 +269,12 @@
/* Begin PBXFileReference section */
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = "<group>"; };
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = "<group>"; };
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = "<group>"; };
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = "<group>"; };
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = "<group>"; };
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = "<group>"; };
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = "<group>"; };
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
00E356F21AD99517003FC87E /* NotificationsExampleAppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationsExampleAppTests.m; sourceTree = "<group>"; };
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = "<group>"; };
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = "<group>"; };
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = "<group>"; };
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* NotificationsExampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NotificationsExampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = NotificationsExampleApp/AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = NotificationsExampleApp/AppDelegate.m; sourceTree = "<group>"; };
......@@ -284,9 +282,11 @@
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = NotificationsExampleApp/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = NotificationsExampleApp/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = NotificationsExampleApp/main.m; sourceTree = "<group>"; };
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
50F1F08522CE3A9F00FD5829 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = "<group>"; };
50F1F0A022CE3B0600FD5829 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = "<group>"; };
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
D84861172267695100E9103D /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
D85498C21D97B31100DEEE06 /* RNNotifications.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNNotifications.xcodeproj; path = ../../RNNotifications/RNNotifications.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */
......@@ -296,145 +296,147 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
50F1F0D722CE3C1E00FD5829 /* libcxxreact.a in Frameworks */,
50F1F0D622CE3C0F00FD5829 /* libyoga.a in Frameworks */,
50F1F0CD22CE3B6300FD5829 /* libRCTActionSheet.a in Frameworks */,
50F1F0CF22CE3B6300FD5829 /* libRCTImage.a in Frameworks */,
50F1F0D022CE3B6300FD5829 /* libRCTLinking.a in Frameworks */,
50F1F0D122CE3B6300FD5829 /* libRCTNetwork.a in Frameworks */,
50F1F0D222CE3B6300FD5829 /* libRCTSettings.a in Frameworks */,
50F1F0D322CE3B6300FD5829 /* libRCTText.a in Frameworks */,
50F1F0D422CE3B6300FD5829 /* libRCTVibration.a in Frameworks */,
50F1F0D522CE3B6300FD5829 /* libRCTWebSocket.a in Frameworks */,
50F1F0CC22CE3B4700FD5829 /* libReact.a in Frameworks */,
D84861182267695100E9103D /* JavaScriptCore.framework in Frameworks */,
D85498D21D97B37F00DEEE06 /* libRNNotifications.a in Frameworks */,
146834051AC3E58100842450 /* libReact.a in Frameworks */,
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,
00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */,
133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */,
00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */,
139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */,
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
00C302A81ABCB8CE00DB3ED1 /* Products */ = {
00E356EF1AD99517003FC87E /* NotificationsExampleAppTests */ = {
isa = PBXGroup;
children = (
00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */,
00E356F21AD99517003FC87E /* NotificationsExampleAppTests.m */,
00E356F01AD99517003FC87E /* Supporting Files */,
);
name = Products;
path = NotificationsExampleAppTests;
sourceTree = "<group>";
};
00C302B61ABCB90400DB3ED1 /* Products */ = {
00E356F01AD99517003FC87E /* Supporting Files */ = {
isa = PBXGroup;
children = (
00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */,
00E356F11AD99517003FC87E /* Info.plist */,
);
name = Products;
name = "Supporting Files";
sourceTree = "<group>";
};
00C302BC1ABCB91800DB3ED1 /* Products */ = {
13B07FAE1A68108700A75B9A /* NotificationsExampleApp */ = {
isa = PBXGroup;
children = (
00C302C01ABCB91800DB3ED1 /* libRCTImage.a */,
18BA9BF11DEC2288001F416D /* libRCTImage-tvOS.a */,
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.m */,
13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB61A68108700A75B9A /* Info.plist */,
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
13B07FB71A68108700A75B9A /* main.m */,
);
name = Products;
name = NotificationsExampleApp;
sourceTree = "<group>";
};
00C302D41ABCB9D200DB3ED1 /* Products */ = {
50F1F04D22CE3A6100FD5829 /* Products */ = {
isa = PBXGroup;
children = (
00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */,
18BA9BF91DEC2288001F416D /* libRCTNetwork-tvOS.a */,
50F1F06022CE3A6100FD5829 /* libReact.a */,
50F1F06222CE3A6100FD5829 /* libReact.a */,
50F1F06422CE3A6100FD5829 /* libyoga.a */,
50F1F06622CE3A6100FD5829 /* libyoga.a */,
50F1F06822CE3A6100FD5829 /* libcxxreact.a */,
50F1F06A22CE3A6100FD5829 /* libcxxreact.a */,
50F1F07022CE3A6100FD5829 /* libjsinspector.a */,
50F1F07222CE3A6100FD5829 /* libjsinspector-tvOS.a */,
50F1F07422CE3A6100FD5829 /* libthird-party.a */,
50F1F07622CE3A6100FD5829 /* libthird-party.a */,
50F1F07822CE3A6100FD5829 /* libdouble-conversion.a */,
50F1F07A22CE3A6100FD5829 /* libdouble-conversion.a */,
50E49F4122D1F06C007160C1 /* libjsi.a */,
50E49F4322D1F06C007160C1 /* libjsiexecutor.a */,
50E49F4522D1F06C007160C1 /* libjsi-tvOS.a */,
50E49F4722D1F06C007160C1 /* libjsiexecutor-tvOS.a */,
);
name = Products;
sourceTree = "<group>";
};
00C302E01ABCB9EE00DB3ED1 /* Products */ = {
50F1F08622CE3A9F00FD5829 /* Products */ = {
isa = PBXGroup;
children = (
00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */,
50F1F08A22CE3AA000FD5829 /* libRCTActionSheet.a */,
);
name = Products;
sourceTree = "<group>";
};
00E356EF1AD99517003FC87E /* NotificationsExampleAppTests */ = {
50F1F09022CE3ABE00FD5829 /* Products */ = {
isa = PBXGroup;
children = (
00E356F21AD99517003FC87E /* NotificationsExampleAppTests.m */,
00E356F01AD99517003FC87E /* Supporting Files */,
50F1F09522CE3ABE00FD5829 /* libRCTImage.a */,
50F1F09722CE3ABE00FD5829 /* libRCTImage-tvOS.a */,
);
path = NotificationsExampleAppTests;
name = Products;
sourceTree = "<group>";
};
00E356F01AD99517003FC87E /* Supporting Files */ = {
50F1F09822CE3ACA00FD5829 /* Products */ = {
isa = PBXGroup;
children = (
00E356F11AD99517003FC87E /* Info.plist */,
50F1F09D22CE3ACA00FD5829 /* libRCTLinking.a */,
50F1F09F22CE3ACA00FD5829 /* libRCTLinking-tvOS.a */,
);
name = "Supporting Files";
name = Products;
sourceTree = "<group>";
};
139105B71AF99BAD00B5F7CC /* Products */ = {
50F1F0A122CE3B0600FD5829 /* Products */ = {
isa = PBXGroup;
children = (
139105C11AF99BAD00B5F7CC /* libRCTSettings.a */,
18BA9BFD1DEC2288001F416D /* libRCTSettings-tvOS.a */,
50F1F0A622CE3B0600FD5829 /* libRCTNetwork.a */,
50F1F0A822CE3B0600FD5829 /* libRCTNetwork-tvOS.a */,
);
name = Products;
sourceTree = "<group>";
};
139FDEE71B06529A00C62182 /* Products */ = {
50F1F0A922CE3B1000FD5829 /* Products */ = {
isa = PBXGroup;
children = (
139FDEF41B06529B00C62182 /* libRCTWebSocket.a */,
18BA9C061DEC2288001F416D /* libRCTWebSocket-tvOS.a */,
18B5569C2007789B007ACD82 /* libfishhook.a */,
18B5569E2007789B007ACD82 /* libfishhook-tvOS.a */,
50F1F0AE22CE3B1000FD5829 /* libRCTSettings.a */,
50F1F0B022CE3B1000FD5829 /* libRCTSettings-tvOS.a */,
);
name = Products;
sourceTree = "<group>";
};
13B07FAE1A68108700A75B9A /* NotificationsExampleApp */ = {
50F1F0B122CE3B1A00FD5829 /* Products */ = {
isa = PBXGroup;
children = (
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.m */,
13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB61A68108700A75B9A /* Info.plist */,
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
13B07FB71A68108700A75B9A /* main.m */,
50F1F0B622CE3B1A00FD5829 /* libRCTText.a */,
50F1F0B822CE3B1A00FD5829 /* libRCTText-tvOS.a */,
);
name = NotificationsExampleApp;
name = Products;
sourceTree = "<group>";
};
146834001AC3E56700842450 /* Products */ = {
50F1F0B922CE3B2400FD5829 /* Products */ = {
isa = PBXGroup;
children = (
146834041AC3E56700842450 /* libReact.a */,
18BA9C0A1DEC2288001F416D /* libReact.a */,
18B556AE2007789B007ACD82 /* libyoga.a */,
18B556B02007789B007ACD82 /* libyoga.a */,
18B556B22007789B007ACD82 /* libcxxreact.a */,
18B556B42007789B007ACD82 /* libcxxreact.a */,
D848610B2267695100E9103D /* libjsinspector.a */,
D848610D2267695100E9103D /* libjsinspector-tvOS.a */,
18B556BA2007789B007ACD82 /* libthird-party.a */,
18B556BC2007789B007ACD82 /* libthird-party.a */,
18B556BE2007789B007ACD82 /* libdouble-conversion.a */,
18B556C02007789B007ACD82 /* libdouble-conversion.a */,
D848610F2267695100E9103D /* libjsi.a */,
D84861112267695100E9103D /* libjsiexecutor.a */,
D84861132267695100E9103D /* libjsi-tvOS.a */,
D84861152267695100E9103D /* libjsiexecutor-tvOS.a */,
50F1F0BD22CE3B2400FD5829 /* libRCTVibration.a */,
);
name = Products;
sourceTree = "<group>";
};
78C398B11ACF4ADC00677621 /* Products */ = {
50F1F0BE22CE3B2E00FD5829 /* Products */ = {
isa = PBXGroup;
children = (
78C398B91ACF4ADC00677621 /* libRCTLinking.a */,
18BA9BF51DEC2288001F416D /* libRCTLinking-tvOS.a */,
50F1F0C522CE3B2E00FD5829 /* libRCTWebSocket.a */,
50F1F0C722CE3B2E00FD5829 /* libRCTWebSocket-tvOS.a */,
50F1F0C922CE3B2E00FD5829 /* libfishhook.a */,
50F1F0CB22CE3B2E00FD5829 /* libfishhook-tvOS.a */,
);
name = Products;
sourceTree = "<group>";
......@@ -442,13 +444,12 @@
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
isa = PBXGroup;
children = (
50F1F0A022CE3B0600FD5829 /* RCTNetwork.xcodeproj */,
D85498C21D97B31100DEEE06 /* RNNotifications.xcodeproj */,
146833FF1AC3E56700842450 /* React.xcodeproj */,
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */,
50F1F08522CE3A9F00FD5829 /* RCTActionSheet.xcodeproj */,
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */,
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */,
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */,
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */,
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,
......@@ -457,15 +458,6 @@
name = Libraries;
sourceTree = "<group>";
};
832341B11AAA6A8300B99B32 /* Products */ = {
isa = PBXGroup;
children = (
832341B51AAA6A8300B99B32 /* libRCTText.a */,
18BA9C011DEC2288001F416D /* libRCTText-tvOS.a */,
);
name = Products;
sourceTree = "<group>";
};
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
......@@ -499,6 +491,7 @@
isa = PBXGroup;
children = (
D85498D11D97B31100DEEE06 /* libRNNotifications.a */,
50E49F4B22D1F06C007160C1 /* RNNotificationsTests.xctest */,
);
name = Products;
sourceTree = "<group>";
......@@ -546,43 +539,39 @@
projectDirPath = "";
projectReferences = (
{
ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */;
ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
},
{
ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */;
ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
ProductGroup = 50F1F08622CE3A9F00FD5829 /* Products */;
ProjectRef = 50F1F08522CE3A9F00FD5829 /* RCTActionSheet.xcodeproj */;
},
{
ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */;
ProductGroup = 50F1F09022CE3ABE00FD5829 /* Products */;
ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
},
{
ProductGroup = 78C398B11ACF4ADC00677621 /* Products */;
ProductGroup = 50F1F09822CE3ACA00FD5829 /* Products */;
ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
},
{
ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */;
ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
ProductGroup = 50F1F0A122CE3B0600FD5829 /* Products */;
ProjectRef = 50F1F0A022CE3B0600FD5829 /* RCTNetwork.xcodeproj */;
},
{
ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */;
ProductGroup = 50F1F0A922CE3B1000FD5829 /* Products */;
ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
},
{
ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
ProductGroup = 50F1F0B122CE3B1A00FD5829 /* Products */;
ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
},
{
ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */;
ProductGroup = 50F1F0B922CE3B2400FD5829 /* Products */;
ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;
},
{
ProductGroup = 139FDEE71B06529A00C62182 /* Products */;
ProductGroup = 50F1F0BE22CE3B2E00FD5829 /* Products */;
ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
},
{
ProductGroup = 146834001AC3E56700842450 /* Products */;
ProductGroup = 50F1F04D22CE3A6100FD5829 /* Products */;
ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
},
{
......@@ -598,235 +587,235 @@
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = {
50E49F4122D1F06C007160C1 /* libjsi.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTActionSheet.a;
remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */;
path = libjsi.a;
remoteRef = 50E49F4022D1F06C007160C1 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = {
50E49F4322D1F06C007160C1 /* libjsiexecutor.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTGeolocation.a;
remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */;
path = libjsiexecutor.a;
remoteRef = 50E49F4222D1F06C007160C1 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = {
50E49F4522D1F06C007160C1 /* libjsi-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTImage.a;
remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */;
path = "libjsi-tvOS.a";
remoteRef = 50E49F4422D1F06C007160C1 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = {
50E49F4722D1F06C007160C1 /* libjsiexecutor-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTNetwork.a;
remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */;
path = "libjsiexecutor-tvOS.a";
remoteRef = 50E49F4622D1F06C007160C1 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = {
50E49F4B22D1F06C007160C1 /* RNNotificationsTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTVibration.a;
remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */;
fileType = wrapper.cfbundle;
path = RNNotificationsTests.xctest;
remoteRef = 50E49F4A22D1F06C007160C1 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = {
50F1F06022CE3A6100FD5829 /* libReact.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTSettings.a;
remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */;
path = libReact.a;
remoteRef = 50F1F05F22CE3A6100FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = {
50F1F06222CE3A6100FD5829 /* libReact.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTWebSocket.a;
remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */;
path = libReact.a;
remoteRef = 50F1F06122CE3A6100FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
146834041AC3E56700842450 /* libReact.a */ = {
50F1F06422CE3A6100FD5829 /* libyoga.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libReact.a;
remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */;
path = libyoga.a;
remoteRef = 50F1F06322CE3A6100FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18B5569C2007789B007ACD82 /* libfishhook.a */ = {
50F1F06622CE3A6100FD5829 /* libyoga.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libfishhook.a;
remoteRef = 18B5569B2007789B007ACD82 /* PBXContainerItemProxy */;
path = libyoga.a;
remoteRef = 50F1F06522CE3A6100FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18B5569E2007789B007ACD82 /* libfishhook-tvOS.a */ = {
50F1F06822CE3A6100FD5829 /* libcxxreact.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libfishhook-tvOS.a";
remoteRef = 18B5569D2007789B007ACD82 /* PBXContainerItemProxy */;
path = libcxxreact.a;
remoteRef = 50F1F06722CE3A6100FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18B556AE2007789B007ACD82 /* libyoga.a */ = {
50F1F06A22CE3A6100FD5829 /* libcxxreact.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libyoga.a;
remoteRef = 18B556AD2007789B007ACD82 /* PBXContainerItemProxy */;
path = libcxxreact.a;
remoteRef = 50F1F06922CE3A6100FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18B556B02007789B007ACD82 /* libyoga.a */ = {
50F1F07022CE3A6100FD5829 /* libjsinspector.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libyoga.a;
remoteRef = 18B556AF2007789B007ACD82 /* PBXContainerItemProxy */;
path = libjsinspector.a;
remoteRef = 50F1F06F22CE3A6100FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18B556B22007789B007ACD82 /* libcxxreact.a */ = {
50F1F07222CE3A6100FD5829 /* libjsinspector-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libcxxreact.a;
remoteRef = 18B556B12007789B007ACD82 /* PBXContainerItemProxy */;
path = "libjsinspector-tvOS.a";
remoteRef = 50F1F07122CE3A6100FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18B556B42007789B007ACD82 /* libcxxreact.a */ = {
50F1F07422CE3A6100FD5829 /* libthird-party.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libcxxreact.a;
remoteRef = 18B556B32007789B007ACD82 /* PBXContainerItemProxy */;
path = "libthird-party.a";
remoteRef = 50F1F07322CE3A6100FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18B556BA2007789B007ACD82 /* libthird-party.a */ = {
50F1F07622CE3A6100FD5829 /* libthird-party.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libthird-party.a";
remoteRef = 18B556B92007789B007ACD82 /* PBXContainerItemProxy */;
remoteRef = 50F1F07522CE3A6100FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18B556BC2007789B007ACD82 /* libthird-party.a */ = {
50F1F07822CE3A6100FD5829 /* libdouble-conversion.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libthird-party.a";
remoteRef = 18B556BB2007789B007ACD82 /* PBXContainerItemProxy */;
path = "libdouble-conversion.a";
remoteRef = 50F1F07722CE3A6100FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18B556BE2007789B007ACD82 /* libdouble-conversion.a */ = {
50F1F07A22CE3A6100FD5829 /* libdouble-conversion.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libdouble-conversion.a";
remoteRef = 18B556BD2007789B007ACD82 /* PBXContainerItemProxy */;
remoteRef = 50F1F07922CE3A6100FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18B556C02007789B007ACD82 /* libdouble-conversion.a */ = {
50F1F08A22CE3AA000FD5829 /* libRCTActionSheet.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libdouble-conversion.a";
remoteRef = 18B556BF2007789B007ACD82 /* PBXContainerItemProxy */;
path = libRCTActionSheet.a;
remoteRef = 50F1F08922CE3AA000FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18BA9BF11DEC2288001F416D /* libRCTImage-tvOS.a */ = {
50F1F09522CE3ABE00FD5829 /* libRCTImage.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libRCTImage-tvOS.a";
remoteRef = 18BA9BF01DEC2288001F416D /* PBXContainerItemProxy */;
path = libRCTImage.a;
remoteRef = 50F1F09422CE3ABE00FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18BA9BF51DEC2288001F416D /* libRCTLinking-tvOS.a */ = {
50F1F09722CE3ABE00FD5829 /* libRCTImage-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libRCTLinking-tvOS.a";
remoteRef = 18BA9BF41DEC2288001F416D /* PBXContainerItemProxy */;
path = "libRCTImage-tvOS.a";
remoteRef = 50F1F09622CE3ABE00FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18BA9BF91DEC2288001F416D /* libRCTNetwork-tvOS.a */ = {
50F1F09D22CE3ACA00FD5829 /* libRCTLinking.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libRCTNetwork-tvOS.a";
remoteRef = 18BA9BF81DEC2288001F416D /* PBXContainerItemProxy */;
path = libRCTLinking.a;
remoteRef = 50F1F09C22CE3ACA00FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18BA9BFD1DEC2288001F416D /* libRCTSettings-tvOS.a */ = {
50F1F09F22CE3ACA00FD5829 /* libRCTLinking-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libRCTSettings-tvOS.a";
remoteRef = 18BA9BFC1DEC2288001F416D /* PBXContainerItemProxy */;
path = "libRCTLinking-tvOS.a";
remoteRef = 50F1F09E22CE3ACA00FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18BA9C011DEC2288001F416D /* libRCTText-tvOS.a */ = {
50F1F0A622CE3B0600FD5829 /* libRCTNetwork.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libRCTText-tvOS.a";
remoteRef = 18BA9C001DEC2288001F416D /* PBXContainerItemProxy */;
path = libRCTNetwork.a;
remoteRef = 50F1F0A522CE3B0600FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18BA9C061DEC2288001F416D /* libRCTWebSocket-tvOS.a */ = {
50F1F0A822CE3B0600FD5829 /* libRCTNetwork-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libRCTWebSocket-tvOS.a";
remoteRef = 18BA9C051DEC2288001F416D /* PBXContainerItemProxy */;
path = "libRCTNetwork-tvOS.a";
remoteRef = 50F1F0A722CE3B0600FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
18BA9C0A1DEC2288001F416D /* libReact.a */ = {
50F1F0AE22CE3B1000FD5829 /* libRCTSettings.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libReact.a;
remoteRef = 18BA9C091DEC2288001F416D /* PBXContainerItemProxy */;
path = libRCTSettings.a;
remoteRef = 50F1F0AD22CE3B1000FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
50F1F0B022CE3B1000FD5829 /* libRCTSettings-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTLinking.a;
remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */;
path = "libRCTSettings-tvOS.a";
remoteRef = 50F1F0AF22CE3B1000FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
50F1F0B622CE3B1A00FD5829 /* libRCTText.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTText.a;
remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
remoteRef = 50F1F0B522CE3B1A00FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D848610B2267695100E9103D /* libjsinspector.a */ = {
50F1F0B822CE3B1A00FD5829 /* libRCTText-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libjsinspector.a;
remoteRef = D848610A2267695100E9103D /* PBXContainerItemProxy */;
path = "libRCTText-tvOS.a";
remoteRef = 50F1F0B722CE3B1A00FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D848610D2267695100E9103D /* libjsinspector-tvOS.a */ = {
50F1F0BD22CE3B2400FD5829 /* libRCTVibration.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libjsinspector-tvOS.a";
remoteRef = D848610C2267695100E9103D /* PBXContainerItemProxy */;
path = libRCTVibration.a;
remoteRef = 50F1F0BC22CE3B2400FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D848610F2267695100E9103D /* libjsi.a */ = {
50F1F0C522CE3B2E00FD5829 /* libRCTWebSocket.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libjsi.a;
remoteRef = D848610E2267695100E9103D /* PBXContainerItemProxy */;
path = libRCTWebSocket.a;
remoteRef = 50F1F0C422CE3B2E00FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D84861112267695100E9103D /* libjsiexecutor.a */ = {
50F1F0C722CE3B2E00FD5829 /* libRCTWebSocket-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libjsiexecutor.a;
remoteRef = D84861102267695100E9103D /* PBXContainerItemProxy */;
path = "libRCTWebSocket-tvOS.a";
remoteRef = 50F1F0C622CE3B2E00FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D84861132267695100E9103D /* libjsi-tvOS.a */ = {
50F1F0C922CE3B2E00FD5829 /* libfishhook.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libjsi-tvOS.a";
remoteRef = D84861122267695100E9103D /* PBXContainerItemProxy */;
path = libfishhook.a;
remoteRef = 50F1F0C822CE3B2E00FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D84861152267695100E9103D /* libjsiexecutor-tvOS.a */ = {
50F1F0CB22CE3B2E00FD5829 /* libfishhook-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libjsiexecutor-tvOS.a";
remoteRef = D84861142267695100E9103D /* PBXContainerItemProxy */;
path = "libfishhook-tvOS.a";
remoteRef = 50F1F0CA22CE3B2E00FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D85498D11D97B31100DEEE06 /* libRNNotifications.a */ = {
......@@ -863,7 +852,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
shellScript = "export NODE_BINARY=node\n../../node_modules/react-native/scripts/react-native-xcode.sh\n";
};
/* End PBXShellScriptBuildPhase section */
......
......@@ -6,6 +6,20 @@
parallelizeBuildables = "NO"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "3D3C04B91DE3340900C268FA"
BuildableName = "libyoga.a"
BlueprintName = "yoga"
ReferencedContainer = "container:../../node_modules/react-native/React/React.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
......@@ -17,7 +31,21 @@
BlueprintIdentifier = "83CBBA2D1A601D0E00E9B192"
BuildableName = "libReact.a"
BlueprintName = "React"
ReferencedContainer = "container:../node_modules/react-native/React/React.xcodeproj">
ReferencedContainer = "container:../../node_modules/react-native/React/React.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "58B511DA1A9E6C8500147676"
BuildableName = "libRNNotifications.a"
BlueprintName = "RNNotifications"
ReferencedContainer = "container:../../RNNotifications/RNNotifications.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
......@@ -40,7 +68,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
......@@ -60,7 +87,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
......
......@@ -9,9 +9,7 @@
#import <UIKit/UIKit.h>
#import <PushKit/PushKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, PKPushRegistryDelegate>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (nonatomic, strong) UIWindow *window;
......
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "AppDelegate.h"
#import "RCTBundleURLProvider.h"
#import "RCTRootView.h"
#import "RNNotifications.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <RNNotifications/RNNotifications.h>
#import <PushKit/PushKit.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSURL *jsCodeLocation;
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"NotificationsExampleApp"
......@@ -34,54 +24,18 @@
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
[RNNotifications startMonitorNotifications];
return YES;
}
// PushKit API Example
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type
{
[RNNotifications didUpdatePushCredentials:credentials forType:type];
}
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
{
[RNNotifications didReceiveRemoteNotification:payload.dictionaryPayload];
}
// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
[RNNotifications didRegisterUserNotificationSettings:notificationSettings];
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[RNNotifications didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the notification event.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification {
[RNNotifications didReceiveRemoteNotification:notification];
}
// Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
[RNNotifications didReceiveLocalNotification:notification];
}
// Required for the notification actions.
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler
{
[RNNotifications handleActionWithIdentifier:identifier forLocalNotification:notification withResponseInfo:responseInfo completionHandler:completionHandler];
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler
{
[RNNotifications handleActionWithIdentifier:identifier forRemoteNotification:userInfo withResponseInfo:responseInfo completionHandler:completionHandler];
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
[RNNotifications didFailToRegisterForRemoteNotificationsWithError:error];
}
@end
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
......@@ -29,6 +39,11 @@
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
</dict>
</plist>
{
"name": "NotificationsExampleApp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start"
},
"dependencies": {
"react": "16.8.3",
"react-native": "0.59.x",
"react-native-notifications": "latest"
}
}
require('./example/index');
\ No newline at end of file
import {NativeModules, DeviceEventEmitter} from "react-native";
import NotificationAndroid from "./notification";
import {NativeModules, DeviceEventEmitter} from 'react-native';
import NotificationAndroid from './notification';
const RNNotifications = NativeModules.WixRNNotifications;
......@@ -10,7 +10,7 @@ let registrationTokenUpdateListener;
export class NotificationsAndroid {
static setNotificationOpenedListener(listener) {
notificationOpenedListener = DeviceEventEmitter.addListener("notificationOpened", (notification) => listener(new NotificationAndroid(notification)));
notificationOpenedListener = DeviceEventEmitter.addListener('notificationOpened', (notification) => listener(new NotificationAndroid(notification)));
}
static clearNotificationOpenedListener() {
......@@ -21,11 +21,11 @@ export class NotificationsAndroid {
}
static setNotificationReceivedListener(listener) {
notificationReceivedListener = DeviceEventEmitter.addListener("notificationReceived", (notification) => listener(new NotificationAndroid(notification)));
notificationReceivedListener = DeviceEventEmitter.addListener('notificationReceived', (notification) => listener(new NotificationAndroid(notification)));
}
static setNotificationReceivedInForegroundListener(listener) {
notificationReceivedInForegroundListener = DeviceEventEmitter.addListener("notificationReceivedInForeground", (notification) => listener(new NotificationAndroid(notification)));
notificationReceivedInForegroundListener = DeviceEventEmitter.addListener('notificationReceivedInForeground', (notification) => listener(new NotificationAndroid(notification)));
}
static clearNotificationReceivedListener() {
......@@ -43,7 +43,7 @@ export class NotificationsAndroid {
}
static setRegistrationTokenUpdateListener(listener) {
registrationTokenUpdateListener = DeviceEventEmitter.addListener("remoteNotificationsRegistered", listener);
registrationTokenUpdateListener = DeviceEventEmitter.addListener('remoteNotificationsRegistered', listener);
}
static clearRegistrationTokenUpdateListener() {
......
/**
* @flow
*/
"use strict";
import { NativeModules, DeviceEventEmitter, NativeAppEventEmitter } from "react-native";
import Map from "core-js/library/es6/map";
import uuid from "uuid";
const NativeRNNotifications = NativeModules.RNNotifications; // eslint-disable-line no-unused-vars
import IOSNotification from "./notification.ios";
export const DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT = "remoteNotificationsRegistered";
export const DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT = "remoteNotificationsRegistrationFailed";
export const DEVICE_PUSH_KIT_REGISTERED_EVENT = "pushKitRegistered";
export const DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT = "notificationReceivedForeground";
export const DEVICE_NOTIFICATION_RECEIVED_BACKGROUND_EVENT = "notificationReceivedBackground";
export const DEVICE_NOTIFICATION_OPENED_EVENT = "notificationOpened";
const DEVICE_NOTIFICATION_ACTION_RECEIVED = "notificationActionReceived";
'use strict';
import { NativeModules, DeviceEventEmitter } from 'react-native';
import Map from 'core-js/library/es6/map';
import uuid from 'uuid';
const NativeRNNotifications = NativeModules.RNBridgeModule; // eslint-disable-line no-unused-vars
import IOSNotification from './notification.ios';
export const DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT = 'remoteNotificationsRegistered';
export const DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT = 'remoteNotificationsRegistrationFailed';
export const DEVICE_PUSH_KIT_REGISTERED_EVENT = 'pushKitRegistered';
export const DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT = 'notificationReceivedForeground';
export const DEVICE_NOTIFICATION_OPENED_EVENT = 'notificationOpened';
export const DEVICE_PUSH_KIT_NOTIFICATION_RECEIVED_EVENT = 'pushKitNotificationReceived';
const _exportedEvents = [
DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT,
DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT,
DEVICE_PUSH_KIT_REGISTERED_EVENT,
DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT,
DEVICE_NOTIFICATION_RECEIVED_BACKGROUND_EVENT,
DEVICE_NOTIFICATION_OPENED_EVENT
DEVICE_NOTIFICATION_OPENED_EVENT,
DEVICE_PUSH_KIT_NOTIFICATION_RECEIVED_EVENT
];
const _notificationHandlers = new Map();
const _actionHandlers = new Map();
let _actionListener;
export class NotificationAction {
options: Object;
handler: Function;
constructor(options: Object, handler: Function) {
constructor(options: Object) {
this.options = options;
this.handler = handler;
}
}
......@@ -56,13 +52,13 @@ export default class NotificationsIOS {
*
* - `remoteNotificationsRegistered` : Fired when the user registers for remote notifications. The handler will be invoked with a hex string representing the deviceToken.
* - `notificationReceivedForeground` : Fired when a notification (local / remote) is received when app is on foreground state.
* - `notificationReceivedBackground`: Fired when a background notification is received.
* - `notificationOpened`: Fired when a notification (local / remote) is opened.
* - `pushKitNotificationReceived` : Fired when a pushKit notification received when app is both on foreground and background state.
*/
static addEventListener(type: string, handler: Function) {
if (_exportedEvents.indexOf(type) !== -1) {
let listener;
if (type === DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT) {
listener = DeviceEventEmitter.addListener(
DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT,
......@@ -78,10 +74,24 @@ export default class NotificationsIOS {
DEVICE_PUSH_KIT_REGISTERED_EVENT,
registration => handler(registration.pushKitToken)
);
} else {
} else if (type === DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT) {
listener = DeviceEventEmitter.addListener(
type,
({payload, identifier}) => handler(new IOSNotification(payload), (presentingOptions) => {
NativeRNNotifications.finishPresentingNotification(identifier, presentingOptions);
})
);
} else if (type === DEVICE_NOTIFICATION_OPENED_EVENT) {
listener = DeviceEventEmitter.addListener(
type,
({payload, identifier, action}) => handler(new IOSNotification(payload), () => {
NativeRNNotifications.finishHandlingAction(identifier);
}, action)
);
} else if (type === DEVICE_PUSH_KIT_NOTIFICATION_RECEIVED_EVENT) {
listener = DeviceEventEmitter.addListener(
type,
notification => handler(new IOSNotification(notification))
(payload) => handler(new IOSNotification(payload))
);
}
......@@ -104,18 +114,6 @@ export default class NotificationsIOS {
}
}
static _actionHandlerDispatcher(action: Object) {
const actionHandler = _actionHandlers.get(action.identifier);
if (actionHandler) {
action.notification = new IOSNotification(action.notification);
actionHandler(action, () => {
NativeRNNotifications.completionHandler(action.completionKey);
});
}
}
/**
* Sets the notification categories
*/
......@@ -123,9 +121,6 @@ export default class NotificationsIOS {
let notificationCategories = [];
if (categories) {
// subscribe once for all actions
_actionListener = NativeAppEventEmitter.addListener(DEVICE_NOTIFICATION_ACTION_RECEIVED, this._actionHandlerDispatcher.bind(this));
notificationCategories = categories.map(category => {
return Object.assign({}, category.options, {
actions: category.options.actions.map(action => {
......@@ -153,10 +148,6 @@ export default class NotificationsIOS {
* memory leaks
*/
static resetCategories() {
if (_actionListener) {
_actionListener.remove();
}
_actionHandlers.clear();
}
......@@ -176,10 +167,6 @@ export default class NotificationsIOS {
NativeRNNotifications.backgroundTimeRemaining(callback);
}
static consumeBackgroundQueue() {
NativeRNNotifications.consumeBackgroundQueue();
}
static log(message: string) {
NativeRNNotifications.log(message);
}
......@@ -198,10 +185,10 @@ export default class NotificationsIOS {
*
* notification is an object containing:
*
* - `alertBody` : The message displayed in the notification alert.
* - `alertTitle` : The message title displayed in the notification.
* - `alertAction` : The "action" displayed beneath an actionable notification. Defaults to "view";
* - `soundName` : The sound played when the notification is fired (optional).
* - `body` : The message displayed in the notification alert.
* - `title` : The message title displayed in the notification.
* - `alertAction` : The 'action' displayed beneath an actionable notification. Defaults to 'view';
* - `sound` : The sound played when the notification is fired (optional).
* - `silent` : If true, the notification sound will be suppressed (optional).
* - `category` : The category of this notification, required for actionable notifications (optional).
* - `userInfo` : An optional object containing additional notification data.
......@@ -254,8 +241,8 @@ export default class NotificationsIOS {
* A delivered notification is an object containing:
*
* - `identifier` : The identifier of this notification.
* - `alertBody` : The message displayed in the notification alert.
* - `alertTitle` : The message title displayed in the notification.
* - `body` : The message displayed in the notification alert.
* - `title` : The message title displayed in the notification.
* - `category` : The category of this notification, if has one.
* - `userInfo` : An optional object containing additional notification data.
* - `thread-id` : The thread identifier of this notification, if has one.
......
......@@ -11,8 +11,8 @@ export default class IOSNotification {
this._data = {};
if (notification.aps &&
notification.aps["content-available"] &&
notification.aps["content-available"] === 1 &&
notification.aps['content-available'] &&
notification.aps['content-available'] === 1 &&
!notification.aps.alert &&
!notification.aps.sound &&
notification.managedAps) {
......@@ -21,8 +21,8 @@ export default class IOSNotification {
this._sound = notification.managedAps.sound;
this._badge = notification.aps.badge;
this._category = notification.managedAps.category;
this._type = "managed";
this._thread = notification.aps["thread-id"];
this._type = 'managed';
this._thread = notification.aps.thread;
} else if (
notification.aps &&
notification.aps.alert) {
......@@ -31,11 +31,11 @@ export default class IOSNotification {
this._sound = notification.aps.sound;
this._badge = notification.aps.badge;
this._category = notification.aps.category;
this._type = "regular";
this._thread = notification.aps["thread-id"];
this._type = 'regular';
this._thread = notification.aps.thread;
}
Object.keys(notification).filter(key => key !== "aps").forEach(key => {
Object.keys(notification).filter(key => key !== 'aps').forEach(key => {
this._data[key] = notification[key];
});
}
......
module.exports = {
projectRoot: `${__dirname}/example`,
watchFolders: [
__dirname,
],
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
},
})
}
};
{
"name": "react-native-notifications",
"version": "1.5.0",
"version": "2.0.0",
"description": "Advanced Push Notifications (Silent, interactive notifications) for iOS & Android",
"author": "Lidan Hifi <lidan.hifi@gmail.com>",
"license": "MIT",
......@@ -19,6 +19,13 @@
"actionable-notifications",
"interactive-notifications"
],
"main": "lib/src/index",
"scripts": {
"pretest": "./node_modules/.bin/eslint *.js test",
"test": "jest",
"start": "node ./scripts/start",
"test-e2e-ios": "node ./scripts/test-e2e --ios"
},
"nativePackage": true,
"dependencies": {
"core-js": "^1.0.0",
......@@ -29,21 +36,27 @@
"react-native": ">=0.25.1"
},
"devDependencies": {
"@types/react": "16.x.x",
"@types/react-native": "0.57.7",
"@types/react-test-renderer": "16.x.x",
"@babel/plugin-proposal-export-default-from": "7.2.0",
"@babel/plugin-proposal-export-namespace-from": "7.2.0",
"typescript": "3.2.2",
"babel-eslint": "9.0.0",
"babel-preset-react-native": "^1.9.0",
"babel-register": "^6.7.2",
"chai": "^3.5.0",
"chokidar-cli": "^1.2.0",
"eslint": "5.1.x",
"eslint": "6.0.1",
"mocha": "^2.5.3",
"proxyquire": "^1.7.4",
"sinon": "^1.17.3",
"sinon-chai": "^2.8.0"
},
"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"
"sinon-chai": "^2.8.0",
"shell-utils": "1.x.x",
"react-native": "0.60.0",
"react": "16.8.6",
"detox": "13.x.x",
"jest": "24.8.0",
"metro-react-native-babel-preset": "0.55.x",
"@babel/register": "7.4.4"
},
"publishConfig": {
"registry": "https://registry.npmjs.org/"
......@@ -56,9 +69,60 @@
"bugs": {
"url": "https://github.com/wix/react-native-notifications/issues"
},
"babel": {
"presets": [
"react-native"
"detox": {
"test-runner": "jest",
"specs": "",
"configurations": {
"ios.none": {
"binaryPath": "playground/ios/DerivedData/playground/Build/Products/Debug-iphonesimulator/playground.app",
"type": "ios.none",
"name": "iPhone X",
"session": {
"server": "ws://localhost:8099",
"sessionId": "playground"
}
},
"ios.sim.debug": {
"binaryPath": "example/ios/DerivedData/NotificationsExampleApp/Build/Products/Debug-iphonesimulator/NotificationsExampleApp.app",
"build": "RCT_NO_LAUNCH_PACKAGER=true xcodebuild build -scheme NotificationsExampleApp -project example/ios/NotificationsExampleApp.xcodeproj -sdk iphonesimulator -configuration Debug -derivedDataPath example/ios/DerivedData/NotificationsExampleApp ONLY_ACTIVE_ARCH=YES -quiet -UseModernBuildSystem=NO",
"type": "ios.simulator",
"name": "iPhone X"
},
"ios.sim.release": {
"binaryPath": "playground/ios/DerivedData/playground/Build/Products/Release-iphonesimulator/playground.app",
"build": "RCT_NO_LAUNCH_PACKAGER=true xcodebuild build -scheme playground_release -project playground/ios/playground.xcodeproj -sdk iphonesimulator -configuration Release -derivedDataPath playground/ios/DerivedData/playground ONLY_ACTIVE_ARCH=YES -quiet -UseModernBuildSystem=NO",
"type": "ios.simulator",
"name": "iPhone X"
}
}
},
"jest": {
"preset": "react-native",
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
},
"roots": [
"<rootDir>/node_modules/",
"<rootDir>/test/"
],
"collectCoverageFrom": [
"lib/src/**/*.js",
"integration/**/*.js",
"!lib/dist/index.js",
"!lib/dist/Navigation.js",
"!lib/dist/adapters/**/*",
"!lib/dist/interfaces/**/*",
"!lib/dist/**/*.test.*",
"!integration/**/*.test.*",
"!integration/*.test.*"
],
"resetMocks": true,
"resetModules": true,
"coverageReporters": [
"json",
"lcov",
"text",
"html"
]
}
}
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`);
}
const _ = require('lodash');
const exec = require('shell-utils').exec;
const android = _.includes(process.argv, '--android');
const release = _.includes(process.argv, '--release');
const skipBuild = _.includes(process.argv, '--skipBuild');
const headless = _.includes(process.argv, '--headless');
const multi = _.includes(process.argv, '--multi');
run();
function run() {
const prefix = android ? `android.emu` : `ios.sim`;
const suffix = release ? `release` : `debug`;
const configuration = `${prefix}.${suffix}`;
const headless$ = android ? headless ? `--headless` : `` : ``;
const workers = multi ? 3 : 1;
if (!skipBuild) {
exec.execSync(`detox build --configuration ${configuration}`);
}
exec.execSync(`detox test --loglevel verbose --configuration ${configuration} ${headless$} ${!android ? `-w ${workers}` : ``}`); //-f "ScreenStyle.test.js" --loglevel trace
}
"use strict";
let expect = require("chai").use(require("sinon-chai")).expect;
import proxyquire from "proxyquire";
import sinon from "sinon";
describe("Notifications-Android > ", () => {
proxyquire.noCallThru();
let refreshTokenStub;
let getInitialNotificationStub;
let postLocalNotificationStub;
let cancelLocalNotificationStub;
let deviceEventEmitterListenerStub;
describe('Notifications-Android', () => {
let libUnderTest;
let deviceEventEmitterListenerStub;
let WixRNNotifications;
beforeEach(() => {
refreshTokenStub = sinon.stub();
getInitialNotificationStub = sinon.stub();
postLocalNotificationStub = sinon.stub();
cancelLocalNotificationStub = sinon.stub();
deviceEventEmitterListenerStub = sinon.stub();
libUnderTest = proxyquire("../index.android", {
"react-native": {
jest.mock('react-native', () => {
return {
NativeModules: {
WixRNNotifications: {
refreshToken: refreshTokenStub,
getInitialNotification: getInitialNotificationStub,
postLocalNotification: postLocalNotificationStub,
cancelLocalNotification: cancelLocalNotificationStub
refreshToken: jest.fn(),
getInitialNotification: jest.fn(),
postLocalNotification: jest.fn(),
cancelLocalNotification: jest.fn()
}
},
DeviceEventEmitter: {
addListener: deviceEventEmitterListenerStub
addListener: jest.fn()
}
},
"./notification": require("../notification.android")
};
});
deviceEventEmitterListenerStub = require('react-native').DeviceEventEmitter.addListener;
WixRNNotifications = require('react-native').NativeModules.WixRNNotifications;
libUnderTest = require('../lib/src/index.android');
});
describe("Registration token API", () => {
it("should assign callback to native event upon listener registration", () => {
expect(deviceEventEmitterListenerStub).to.not.have.been.called;
describe('Registration token API', () => {
it('should assign callback to native event upon listener registration', () => {
expect(deviceEventEmitterListenerStub).toHaveBeenCalledTimes(0);
const userListener = () => {};
libUnderTest.NotificationsAndroid.setRegistrationTokenUpdateListener(userListener);
expect(deviceEventEmitterListenerStub).to.have.been.calledWith("remoteNotificationsRegistered", userListener);
expect(deviceEventEmitterListenerStub).to.have.been.calledOnce;
expect(deviceEventEmitterListenerStub).toHaveBeenCalledWith('remoteNotificationsRegistered', userListener);
expect(deviceEventEmitterListenerStub).toHaveBeenCalledTimes(1);
});
it("should clear native event listener upon listener deregister", () => {
expect(deviceEventEmitterListenerStub).to.not.have.been.called;
it('should clear native event listener upon listener deregister', () => {
expect(deviceEventEmitterListenerStub).toHaveBeenCalledTimes(0);
const userListener = () => {};
const nativeListener = {
remove: sinon.spy()
remove: jest.fn()
};
deviceEventEmitterListenerStub.returns(nativeListener);
deviceEventEmitterListenerStub.mockReturnValueOnce(nativeListener);
libUnderTest.NotificationsAndroid.setRegistrationTokenUpdateListener(userListener);
libUnderTest.NotificationsAndroid.clearRegistrationTokenUpdateListener();
expect(nativeListener.remove).to.have.been.calledOnce;
expect(nativeListener.remove).toHaveBeenCalledTimes(1);
});
it("shouldn't fail if deregister without registering", () => {
it('shouldn`t fail if deregister without registering', () => {
libUnderTest.NotificationsAndroid.clearRegistrationTokenUpdateListener();
expect(deviceEventEmitterListenerStub).to.not.have.been.called;
expect(deviceEventEmitterListenerStub).toHaveBeenCalledTimes(0);
});
});
describe("notification-opening API", () => {
it("should assign callback to native event upon registration", () => {
expect(deviceEventEmitterListenerStub).to.not.have.been.called;
const userListenerStub = sinon.stub();
describe('notification-opening API', () => {
it('should assign callback to native event upon registration', () => {
expect(deviceEventEmitterListenerStub).toHaveBeenCalledTimes(0);
const userListenerStub = jest.fn();
libUnderTest.NotificationsAndroid.setNotificationOpenedListener(userListenerStub);
expect(deviceEventEmitterListenerStub).to.have.been.calledOnce;
expect(deviceEventEmitterListenerStub).to.have.been.calledWith("notificationOpened", sinon.match.func);
expect(deviceEventEmitterListenerStub).toHaveBeenCalledTimes(1);
expect(deviceEventEmitterListenerStub).toHaveBeenCalledWith('notificationOpened', expect.any(Function));
});
it("should assign a wrapper-callback upon registration", () => {
expect(deviceEventEmitterListenerStub).to.not.have.been.called;
const userListenerStub = sinon.stub();
const notification = { foo: "bar" };
it('should assign a wrapper-callback upon registration', () => {
expect(deviceEventEmitterListenerStub).toHaveBeenCalledTimes(0);
const userListenerStub = jest.fn();
const notification = { foo: 'bar' };
libUnderTest.NotificationsAndroid.setNotificationOpenedListener(userListenerStub);
expect(userListenerStub).to.not.have.been.called;
deviceEventEmitterListenerStub.args[0][1](notification);
expect(userListenerStub).to.have.been.calledOnce;
expect(userListenerStub.args[0][0].getData()).to.equal(notification);
expect(userListenerStub).toHaveBeenCalledTimes(0);
deviceEventEmitterListenerStub.mock.calls[0][1](notification);
expect(userListenerStub).toHaveBeenCalledTimes(1);
expect(userListenerStub.mock.calls[0][0].getData()).toEqual(notification);
});
it("should clear native event listener upon listener deregister", () => {
expect(deviceEventEmitterListenerStub).to.not.have.been.called;
it('should clear native event listener upon listener deregister', () => {
expect(deviceEventEmitterListenerStub).toHaveBeenCalledTimes(0);
const userListener = () => {};
const nativeListener = {
remove: sinon.spy()
remove: jest.fn()
};
deviceEventEmitterListenerStub.returns(nativeListener);
deviceEventEmitterListenerStub.mockReturnValueOnce(nativeListener);
libUnderTest.NotificationsAndroid.setNotificationOpenedListener(userListener);
libUnderTest.NotificationsAndroid.clearNotificationOpenedListener();
expect(nativeListener.remove).to.have.been.calledOnce;
expect(nativeListener.remove).toHaveBeenCalledTimes(1);
});
it("shouldn't fail if deregister without registering", () => {
it('shouldnt fail if deregister without registering', () => {
libUnderTest.NotificationsAndroid.clearNotificationOpenedListener();
expect(deviceEventEmitterListenerStub).to.not.have.been.called;
expect(deviceEventEmitterListenerStub).toHaveBeenCalledTimes(0);
});
});
describe("notification-receive API", () => {
it("should assign callback to native event upon registration", () => {
expect(deviceEventEmitterListenerStub).to.not.have.been.called;
const userListenerStub = sinon.stub();
describe('notification-receive API', () => {
it('should assign callback to native event upon registration', () => {
expect(deviceEventEmitterListenerStub).toHaveBeenCalledTimes(0);
const userListenerStub = jest.fn();
libUnderTest.NotificationsAndroid.setNotificationReceivedListener(userListenerStub);
expect(deviceEventEmitterListenerStub).to.have.been.calledOnce;
expect(deviceEventEmitterListenerStub).to.have.been.calledWith("notificationReceived", sinon.match.func);
expect(deviceEventEmitterListenerStub).toHaveBeenCalledTimes(1);
expect(deviceEventEmitterListenerStub).toHaveBeenCalledWith('notificationReceived', expect.any(Function));
});
it("should assign a wrapper-callback upon registration", () => {
expect(deviceEventEmitterListenerStub).to.not.have.been.called;
const userListenerStub = sinon.stub();
const notification = { foo: "bar" };
it('should assign a wrapper-callback upon registration', () => {
expect(deviceEventEmitterListenerStub).toHaveBeenCalledTimes(0);
const userListenerStub = jest.fn();
const notification = { foo: 'bar' };
libUnderTest.NotificationsAndroid.setNotificationReceivedListener(userListenerStub);
expect(userListenerStub).to.not.have.been.called;
deviceEventEmitterListenerStub.args[0][1](notification);
expect(userListenerStub).to.have.been.calledOnce;
expect(userListenerStub.args[0][0].getData()).to.equal(notification);
expect(userListenerStub).toHaveBeenCalledTimes(0);
deviceEventEmitterListenerStub.mock.calls[0][1](notification);
expect(userListenerStub).toHaveBeenCalledTimes(1);
expect(userListenerStub.mock.calls[0][0].getData()).toEqual(notification);
});
it("should clear native event listener upon listener deregister", () => {
expect(deviceEventEmitterListenerStub).to.not.have.been.called;
it('should clear native event listener upon listener deregister', () => {
expect(deviceEventEmitterListenerStub).toHaveBeenCalledTimes(0);
const userListener = () => {};
const nativeListener = {
remove: sinon.spy()
remove: jest.fn()
};
deviceEventEmitterListenerStub.returns(nativeListener);
deviceEventEmitterListenerStub.mockReturnValueOnce(nativeListener);
libUnderTest.NotificationsAndroid.setNotificationReceivedListener(userListener);
libUnderTest.NotificationsAndroid.clearNotificationReceivedListener();
expect(nativeListener.remove).to.have.been.calledOnce;
expect(nativeListener.remove).toHaveBeenCalledTimes(1);
});
it("shouldn't fail if deregister without registering", () => {
it('shouldn`t fail if deregister without registering', () => {
libUnderTest.NotificationsAndroid.clearNotificationReceivedListener();
expect(deviceEventEmitterListenerStub).to.not.have.been.called;
expect(deviceEventEmitterListenerStub).toHaveBeenCalledTimes(0);
});
});
describe("Notification token", () => {
it("should refresh notification token upon refreshing request by the user", () => {
expect(refreshTokenStub).to.not.have.been.called;
describe('Notification token', () => {
it('should refresh notification token upon refreshing request by the user', () => {
expect(WixRNNotifications.refreshToken).toHaveBeenCalledTimes(0);
libUnderTest.NotificationsAndroid.refreshToken();
expect(refreshTokenStub).to.have.been.calledOnce;
expect(WixRNNotifications.refreshToken).toHaveBeenCalledTimes(1);
});
});
describe("Initial notification API", () => {
it("should return initial notification data if available", (done) => {
expect(getInitialNotificationStub).to.not.have.been.called;
const rawNotification = {foo: "bar"};
getInitialNotificationStub.returns(Promise.resolve(rawNotification));
describe('Initial notification API', () => {
it('should return initial notification data if available', (done) => {
expect(WixRNNotifications.getInitialNotification).toHaveBeenCalledTimes(0);
const rawNotification = {foo: 'bar'};
WixRNNotifications.getInitialNotification.mockReturnValueOnce(Promise.resolve(rawNotification));
libUnderTest.PendingNotifications.getInitialNotification()
.then((notification) => {
expect(notification.getData()).to.equal(rawNotification);
expect(notification.getData()).toEqual(rawNotification);
done();
})
.catch((err) => done(err));
});
it("should return empty notification if not available", (done) => {
expect(getInitialNotificationStub).to.not.have.been.called;
getInitialNotificationStub.returns(Promise.resolve(null));
it('should return empty notification if not available', (done) => {
expect(WixRNNotifications.getInitialNotification).toHaveBeenCalledTimes(0);
WixRNNotifications.getInitialNotification.mockReturnValueOnce(Promise.resolve(null));
libUnderTest.PendingNotifications.getInitialNotification()
.then((notification) => {
expect(notification).to.be.undefined;
expect(notification).toBeUndefined();
done();
})
.catch((err) => done(err));
......@@ -195,37 +183,36 @@ describe("Notifications-Android > ", () => {
});
describe("Local notification", () => {
describe('Local notification', () => {
const notification = {
title: "notification-title",
body: "notification-body"
title: 'notification-title',
body: 'notification-body'
};
it("should get published when posted manually", () => {
expect(postLocalNotificationStub).to.not.have.been.called;
it('should get published when posted manually', () => {
expect(WixRNNotifications.postLocalNotification).toHaveBeenCalledTimes(0);
const id = libUnderTest.NotificationsAndroid.localNotification(notification);
expect(id).to.not.be.undefined;
expect(postLocalNotificationStub).to.have.been.calledWith(notification, id);
expect(id).toBeDefined();
expect(WixRNNotifications.postLocalNotification).toHaveBeenCalledWith(notification, id);
});
it("should be called with a unique ID", () => {
expect(postLocalNotificationStub).to.not.have.been.called;
it('should be called with a unique ID', () => {
expect(WixRNNotifications.postLocalNotification).toHaveBeenCalledTimes(0);
const id = libUnderTest.NotificationsAndroid.localNotification(notification);
const id2 = libUnderTest.NotificationsAndroid.localNotification(notification);
expect(id).to.not.be.undefined;
expect(id2).to.not.be.undefined;
expect(id).to.not.equal(id2);
expect(id).toBeDefined();
expect(id2).toBeDefined();
expect(id).not.toBe(id2);
});
it("should be cancellable with an ID", () => {
expect(cancelLocalNotificationStub).to.not.have.been.called;
it('should be cancellable with an ID', () => {
expect(WixRNNotifications.cancelLocalNotification).toHaveBeenCalledTimes(0);
libUnderTest.NotificationsAndroid.cancelLocalNotification(666);
expect(cancelLocalNotificationStub).to.have.been.calledWith(666);
expect(WixRNNotifications.cancelLocalNotification).toHaveBeenCalledWith(666);
});
});
});
"use strict";
let expect = require("chai").use(require("sinon-chai")).expect;
import proxyquire from "proxyquire";
import sinon from "sinon";
/* eslint-disable no-unused-vars */
describe("NotificationsIOS", () => {
describe('NotificationsIOS', () => {
let deviceEvents = [
"pushKitRegistered",
"remoteNotificationsRegistered",
"remoteNotificationsRegistrationFailed",
"notificationReceivedForeground",
"notificationReceivedBackground",
"notificationOpened"
'pushKitRegistered',
'remoteNotificationsRegistered',
'remoteNotificationsRegistrationFailed',
'notificationReceivedForeground',
'notificationOpened'
];
/*eslint-disable indent*/
let deviceAddEventListener,
deviceRemoveEventListener,
nativeAppAddEventListener,
nativeAppRemoveEventListener,
nativeRequestPermissionsWithCategories,
nativeAbandonPermissions,
nativeRegisterPushKit,
nativeBackgroundTimeRemaining,
nativeConsumeBackgroundQueue,
nativeLocalNotification,
nativeCancelLocalNotification,
nativeCancelAllLocalNotifications,
nativeGetBadgesCount,
nativeSetBadgesCount,
nativeIsRegisteredForRemoteNotifications,
nativeCheckPermissions,
nativeRemoveAllDeliveredNotifications,
nativeRemoveDeliveredNotifications,
nativeGetDeliveredNotifications;
let NotificationsIOS, NotificationAction, NotificationCategory;
let constantGuid = 'some-random-uuid';
let identifiers = ['some-random-uuid', 'other-random-uuid'];
let someHandler = () => {};
let constantGuid = "some-random-uuid";
let identifiers = ["some-random-uuid", "other-random-uuid"];
/*eslint-enable indent*/
before(() => {
deviceAddEventListener = sinon.spy();
deviceRemoveEventListener = sinon.spy();
nativeAppAddEventListener = sinon.spy();
nativeAppRemoveEventListener = sinon.spy();
nativeRequestPermissionsWithCategories = sinon.spy();
nativeAbandonPermissions = sinon.spy();
nativeRegisterPushKit = sinon.spy();
nativeBackgroundTimeRemaining = sinon.spy();
nativeConsumeBackgroundQueue = sinon.spy();
nativeLocalNotification = sinon.spy();
nativeCancelLocalNotification = sinon.spy();
nativeCancelAllLocalNotifications = sinon.spy();
nativeGetBadgesCount = sinon.spy();
nativeSetBadgesCount = sinon.spy();
nativeIsRegisteredForRemoteNotifications = sinon.spy();
nativeCheckPermissions = sinon.spy();
nativeRemoveAllDeliveredNotifications = sinon.spy();
nativeRemoveDeliveredNotifications = sinon.spy();
nativeGetDeliveredNotifications = sinon.spy();
let libUnderTest = proxyquire("../index.ios", {
"uuid": {
v4: () => constantGuid
},
"react-native": {
let nativeModule;
let DeviceEventEmitter;
beforeEach(() => {
jest.mock('react-native', () => {
const RNBridgeModule = {
requestPermissionsWithCategories: jest.fn(),
abandonPermissions: jest.fn(),
registerPushKit: jest.fn(),
backgroundTimeRemaining: jest.fn(),
localNotification: jest.fn(),
cancelLocalNotification: jest.fn(),
cancelAllLocalNotifications: jest.fn(),
getBadgesCount: jest.fn(),
setBadgesCount: jest.fn(),
isRegisteredForRemoteNotifications: jest.fn(),
checkPermissions: jest.fn(),
removeAllDeliveredNotifications: jest.fn(),
removeDeliveredNotifications: jest.fn(),
getDeliveredNotifications: jest.fn()
};
return {
NativeModules: {
RNNotifications: {
requestPermissionsWithCategories: nativeRequestPermissionsWithCategories,
abandonPermissions: nativeAbandonPermissions,
registerPushKit: nativeRegisterPushKit,
backgroundTimeRemaining: nativeBackgroundTimeRemaining,
consumeBackgroundQueue: nativeConsumeBackgroundQueue,
localNotification: nativeLocalNotification,
cancelLocalNotification: nativeCancelLocalNotification,
cancelAllLocalNotifications: nativeCancelAllLocalNotifications,
getBadgesCount: nativeGetBadgesCount,
setBadgesCount: nativeSetBadgesCount,
isRegisteredForRemoteNotifications: nativeIsRegisteredForRemoteNotifications,
checkPermissions: nativeCheckPermissions,
removeAllDeliveredNotifications: nativeRemoveAllDeliveredNotifications,
removeDeliveredNotifications: nativeRemoveDeliveredNotifications,
getDeliveredNotifications: nativeGetDeliveredNotifications
}
},
NativeAppEventEmitter: {
addListener: (...args) => {
nativeAppAddEventListener(...args);
return { remove: nativeAppRemoveEventListener };
}
RNBridgeModule
},
DeviceEventEmitter: {
addListener: (...args) => {
deviceAddEventListener(...args);
addListener: jest.fn(() => {
return {
remove: jest.fn()
};
})
}
};
});
return { remove: deviceRemoveEventListener };
}
},
"@noCallThru": true
}
nativeModule = require('react-native').NativeModules.RNBridgeModule;
DeviceEventEmitter = require('react-native').DeviceEventEmitter;
jest.mock('uuid', () => {
return {
v4: () => 'some-random-uuid'
};
});
let libUnderTest = require('../lib/src/index.ios');
NotificationsIOS = libUnderTest.default;
NotificationAction = libUnderTest.NotificationAction;
NotificationCategory = libUnderTest.NotificationCategory;
});
afterEach(() => {
deviceAddEventListener.reset();
deviceRemoveEventListener.reset();
nativeAppAddEventListener.reset();
nativeAppRemoveEventListener.reset();
nativeRequestPermissionsWithCategories.reset();
nativeAbandonPermissions.reset();
nativeRegisterPushKit.reset();
nativeBackgroundTimeRemaining.reset();
nativeConsumeBackgroundQueue.reset();
nativeLocalNotification.reset();
nativeCancelLocalNotification.reset();
nativeCancelAllLocalNotifications.reset();
nativeIsRegisteredForRemoteNotifications.reset();
nativeCheckPermissions.reset();
nativeRemoveAllDeliveredNotifications.reset();
nativeRemoveDeliveredNotifications.reset();
nativeGetDeliveredNotifications.reset();
});
after(() => {
deviceAddEventListener = null;
deviceRemoveEventListener = null;
nativeAppAddEventListener = null;
nativeAppRemoveEventListener = null;
nativeRequestPermissionsWithCategories = null;
nativeAbandonPermissions = null;
nativeRegisterPushKit = null;
nativeBackgroundTimeRemaining = null;
nativeConsumeBackgroundQueue = null;
nativeLocalNotification = null;
nativeCancelLocalNotification = null;
nativeCancelAllLocalNotifications = null;
nativeIsRegisteredForRemoteNotifications = null;
nativeCheckPermissions = null;
nativeRemoveAllDeliveredNotifications = null;
nativeRemoveDeliveredNotifications = null;
nativeGetDeliveredNotifications = null;
NotificationsIOS = null;
NotificationAction = null;
NotificationCategory = null;
});
describe("Add Event Listener", () => {
describe('Add Event Listener', () => {
deviceEvents.forEach(event => {
it(`should subscribe the given handler to device event: ${event}`, () => {
NotificationsIOS.addEventListener(event, someHandler);
expect(deviceAddEventListener).to.have.been.calledWith(event, sinon.match.func);
expect(DeviceEventEmitter.addListener).toHaveBeenCalledWith(event, expect.any(Function));
});
});
it("should not subscribe to unknown device events", () => {
NotificationsIOS.addEventListener("someUnsupportedEvent", someHandler);
it('should not subscribe to unknown device events', () => {
NotificationsIOS.addEventListener('someUnsupportedEvent', someHandler);
expect(deviceAddEventListener).to.not.have.been.called;
expect(DeviceEventEmitter.addListener).toHaveBeenCalledTimes(0);
});
});
describe("Remove Event Listener", () => {
describe('Remove Event Listener', () => {
deviceEvents.forEach(event => {
it(`should unsubscribe the given handler from device event: ${event}`, () => {
const removeCallback = jest.fn();
DeviceEventEmitter.addListener.mockReturnValueOnce({
remove: removeCallback
});
NotificationsIOS.addEventListener(event, someHandler);
NotificationsIOS.removeEventListener(event, someHandler);
expect(deviceRemoveEventListener).to.have.been.calledOnce;
expect(removeCallback).toHaveBeenCalledTimes(1);
});
});
it("should not unsubscribe to unknown device events", () => {
let someUnsupportedEvent = "someUnsupportedEvent";
it('should not unsubscribe to unknown device events', () => {
let someUnsupportedEvent = 'someUnsupportedEvent';
const removeCallback = jest.fn();
DeviceEventEmitter.addListener.mockReturnValueOnce({
remove: removeCallback
});
NotificationsIOS.addEventListener(someUnsupportedEvent, someHandler);
NotificationsIOS.removeEventListener(someUnsupportedEvent, someHandler);
expect(deviceRemoveEventListener).to.not.have.been.called;
expect(removeCallback).toHaveBeenCalledTimes(0);
});
});
describe("Notification actions handling", () => {
describe('Notification actions handling', () => {
let someAction, someCategory;
let actionOpts = {
activationMode: "foreground",
title: "someAction",
behavior: "default",
identifier: "SOME_ACTION"
activationMode: 'foreground',
title: 'someAction',
behavior: 'default',
identifier: 'SOME_ACTION'
};
beforeEach(() => {
someAction = new NotificationAction(actionOpts, () => {});
someCategory = new NotificationCategory({
identifier: "SOME_CATEGORY",
identifier: 'SOME_CATEGORY',
actions: [someAction],
context: "default"
context: 'default'
});
});
describe("register push notifications", () => {
it("should call native request permissions with array of categories", () => {
describe('register push notifications', () => {
it('should call native request permissions with array of categories', () => {
NotificationsIOS.requestPermissions([someCategory]);
expect(nativeRequestPermissionsWithCategories).to.have.been.calledWith([{
identifier: "SOME_CATEGORY",
expect(nativeModule.requestPermissionsWithCategories).toHaveBeenCalledWith([{
identifier: 'SOME_CATEGORY',
actions: [actionOpts],
context: "default"
context: 'default'
}]);
});
it("should call native request permissions with empty array if no categories specified", () => {
it('should call native request permissions with empty array if no categories specified', () => {
NotificationsIOS.requestPermissions();
expect(nativeRequestPermissionsWithCategories).to.have.been.calledWith([]);
});
it("should subscribe to 'notificationActionReceived' event once, with a single event handler", () => {
NotificationsIOS.requestPermissions([someCategory]);
expect(nativeAppAddEventListener).to.have.been.calledOnce;
expect(nativeAppAddEventListener).to.have.been.calledWith("notificationActionReceived", sinon.match.func);
expect(nativeModule.requestPermissionsWithCategories).toHaveBeenCalledWith([]);
});
});
describe("reset categories", () => {
it("should remove 'notificationActionReceived' event handler", () => {
NotificationsIOS.resetCategories();
expect(nativeAppRemoveEventListener).to.have.been.calledOnce;
});
});
describe("get badges count", () => {
it("should call native getBadgesCount", () => {
describe('get badges count', () => {
it('should call native getBadgesCount', () => {
const callback = (count) => console.log(count);
NotificationsIOS.getBadgesCount(callback);
expect(nativeGetBadgesCount).to.have.been.calledWith(callback);
expect(nativeModule.getBadgesCount).toHaveBeenCalledWith(callback);
});
});
describe("set badges count", () => {
it("should call native setBadgesCount", () => {
describe('set badges count', () => {
it('should call native setBadgesCount', () => {
NotificationsIOS.setBadgesCount(44);
expect(nativeSetBadgesCount).to.have.been.calledWith(44);
expect(nativeModule.setBadgesCount).toHaveBeenCalledWith(44);
});
});
});
describe("register push kit for background notifications", function () {
it("should call native register push kit method", function () {
describe('register push kit for background notifications', function () {
it('should call native register push kit method', function () {
NotificationsIOS.registerPushKit();
expect(nativeRegisterPushKit).to.have.been.called;
expect(nativeModule.registerPushKit).toHaveBeenCalledTimes(1);
});
});
describe("Abandon push notifications permissions", () => {
it("should call native abandon permissions method", () => {
describe('Abandon push notifications permissions', () => {
it('should call native abandon permissions method', () => {
NotificationsIOS.abandonPermissions();
expect(nativeAbandonPermissions).to.have.been.called;
expect(nativeModule.abandonPermissions).toHaveBeenCalledTimes(1);
});
});
describe("Get background remaining time", () => {
it("should call native background remaining time method", () => {
let someCallback = (time) => { };
describe('Get background remaining time', () => {
it('should call native background remaining time method', () => {
let someCallback = () => {};
NotificationsIOS.backgroundTimeRemaining(someCallback);
expect(nativeBackgroundTimeRemaining).to.have.been.calledWith(someCallback);
});
});
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;
expect(nativeModule.backgroundTimeRemaining).toHaveBeenCalledWith(someCallback);
});
});
describe("Dispatch local notification", () => {
it("should return generated notification guid", () => {
expect(NotificationsIOS.localNotification({})).to.equal(constantGuid);
describe('Dispatch local notification', () => {
it('should return generated notification guid', () => {
expect(NotificationsIOS.localNotification({})).toEqual(constantGuid);
});
it("should call native local notification method with generated notification guid and notification object", () => {
it('should call native local notification method with generated notification guid and notification object', () => {
let someLocalNotification = {
alertBody: "some body",
alertTitle: "some title",
alertAction: "some action",
soundName: "sound",
category: "SOME_CATEGORY",
body: 'some body',
title: 'some title',
alertAction: 'some action',
sound: 'sound',
category: 'SOME_CATEGORY',
userInfo: {
"key": "value"
'key': 'value'
}
};
NotificationsIOS.localNotification(someLocalNotification);
expect(nativeLocalNotification).to.have.been.calledWith(someLocalNotification, constantGuid);
expect(nativeModule.localNotification).toHaveBeenCalledWith(someLocalNotification, constantGuid);
});
});
describe("Cancel local notification", () => {
it("should call native cancel local notification method", () => {
describe('Cancel local notification', () => {
it('should call native cancel local notification method', () => {
NotificationsIOS.cancelLocalNotification(constantGuid);
expect(nativeCancelLocalNotification).to.have.been.calledWith(constantGuid);
expect(nativeModule.cancelLocalNotification).toHaveBeenCalledWith(constantGuid);
});
});
describe("Cancel all local notifications", () => {
it("should call native cancel all local notifications method", () => {
describe('Cancel all local notifications', () => {
it('should call native cancel all local notifications method', () => {
NotificationsIOS.cancelAllLocalNotifications();
expect(nativeCancelAllLocalNotifications).to.have.been.calledWith();
expect(nativeModule.cancelAllLocalNotifications).toHaveBeenCalledWith();
});
});
describe("Is registered for remote notifications ", () => {
it("should call native is registered for remote notifications", () => {
describe('Is registered for remote notifications ', () => {
it('should call native is registered for remote notifications', () => {
NotificationsIOS.isRegisteredForRemoteNotifications();
expect(nativeIsRegisteredForRemoteNotifications).to.have.been.calledWith();
expect(nativeModule.isRegisteredForRemoteNotifications).toHaveBeenCalledWith();
});
});
describe("Check permissions ", () => {
it("should call native check permissions", () => {
describe('Check permissions ', () => {
it('should call native check permissions', () => {
NotificationsIOS.checkPermissions();
expect(nativeCheckPermissions).to.have.been.calledWith();
expect(nativeModule.checkPermissions).toHaveBeenCalledWith();
});
});
describe("Remove all delivered notifications", () => {
it("should call native remove all delivered notifications method", () => {
describe('Remove all delivered notifications', () => {
it('should call native remove all delivered notifications method', () => {
NotificationsIOS.removeAllDeliveredNotifications();
expect(nativeRemoveAllDeliveredNotifications).to.have.been.calledWith();
expect(nativeModule.removeAllDeliveredNotifications).toHaveBeenCalledWith();
});
});
describe("Remove delivered notifications", () => {
it("should call native remove delivered notifications method", () => {
describe('Remove delivered notifications', () => {
it('should call native remove delivered notifications method', () => {
NotificationsIOS.removeDeliveredNotifications(identifiers);
expect(nativeRemoveDeliveredNotifications).to.have.been.calledWith(identifiers);
expect(nativeModule.removeDeliveredNotifications).toHaveBeenCalledWith(identifiers);
});
});
describe("Get delivered notifications", () => {
it("should call native get delivered notifications method", () => {
describe('Get delivered notifications', () => {
it('should call native get delivered notifications method', () => {
const callback = (notifications) => console.log(notifications);
NotificationsIOS.getDeliveredNotifications(callback);
expect(nativeGetDeliveredNotifications).to.have.been.calledWith(callback);
expect(nativeModule.getDeliveredNotifications).toHaveBeenCalledWith(callback);
});
});
});
"use strict";
import { expect } from "chai";
import IOSNotification from "../notification.ios";
import IOSNotification from '../lib/src/notification.ios';
describe("iOS Notification Object", () => {
describe('iOS Notification Object', () => {
let notification;
let someBadgeCount = 123, someSound = "someSound", someCategory = "some_notification_category", someThread = "thread-1";
let someBadgeCount = 123, someSound = 'someSound', someCategory = 'some_notification_category', someThread = 'thread-1';
describe("for a regular iOS push notification", () => {
describe('for a regular iOS push notification', () => {
let regularNativeNotifications = [
// basic example, without content-available = 1 (aka silent notification)
{
aps: {
alert: {
title: "some title",
body: "some body"
title: 'some title',
body: 'some body'
},
badge: someBadgeCount,
sound: someSound,
category: someCategory,
"thread-id": someThread
thread: someThread
},
key1: "value1",
key2: "value2"
key1: 'value1',
key2: 'value2'
},
// another example, with content-available but also with alert object (should not be a silent notification)
{
aps: {
"content-available": 1,
'content-available': 1,
alert: {
title: "some title",
body: "some body"
title: 'some title',
body: 'some body'
},
badge: someBadgeCount,
sound: someSound,
category: someCategory,
"thread-id": someThread
thread: someThread
},
key1: "value1",
key2: "value2"
key1: 'value1',
key2: 'value2'
}
];
......@@ -47,82 +45,82 @@ describe("iOS Notification Object", () => {
notification = new IOSNotification(nativeNotification);
});
it("should return 'regular' type", function () {
expect(notification.getType()).to.equal("regular");
it('should return regular type', function () {
expect(notification.getType()).toEqual('regular');
});
it("should return the alert object", () => {
expect(notification.getMessage()).to.deep.equal(nativeNotification.aps.alert);
it('should return the alert object', () => {
expect(notification.getMessage()).toEqual(nativeNotification.aps.alert);
});
it("should return the sound", () => {
expect(notification.getSound()).to.equal(someSound);
it('should return the sound', () => {
expect(notification.getSound()).toEqual(someSound);
});
it("should return the badge count", () => {
expect(notification.getBadgeCount()).to.equal(someBadgeCount);
it('should return the badge count', () => {
expect(notification.getBadgeCount()).toEqual(someBadgeCount);
});
it("should return the category", () => {
expect(notification.getCategory()).to.equal(someCategory);
it('should return the category', () => {
expect(notification.getCategory()).toEqual(someCategory);
});
it("should return the thread", () => {
expect(notification.getThread()).to.equal("thread-1");
it('should return the thread', () => {
expect(notification.getThread()).toEqual('thread-1');
});
it("should return the custom data", () => {
expect(notification.getData()).to.deep.equal({ key1: "value1", key2: "value2" });
it('should return the custom data', () => {
expect(notification.getData()).toEqual({ key1: 'value1', key2: 'value2' });
});
});
});
describe("for a managed iOS push notification (silent notification, with managedAps key and content-available = 1)", () => {
describe('for a managed iOS push notification (silent notification, with managedAps key and content-available = 1)', () => {
let managedNativeNotification = {
aps: {
"content-available": 1,
'content-available': 1,
badge: someBadgeCount
},
managedAps: {
action: "CREATE",
notificationId: "1",
action: 'CREATE',
notificationId: '1',
alert: {
title: "some title",
body: "some body"
title: 'some title',
body: 'some body'
},
sound: someSound,
category: someCategory
},
key1: "value1",
key2: "value2"
key1: 'value1',
key2: 'value2'
};
beforeEach(() => {
notification = new IOSNotification(managedNativeNotification);
});
it("should return 'managed' type", function () {
expect(notification.getType()).to.equal("managed");
it('should return managed type', function () {
expect(notification.getType()).toEqual('managed');
});
it("should return the alert object", () => {
expect(notification.getMessage()).to.equal(managedNativeNotification.managedAps.alert);
it('should return the alert object', () => {
expect(notification.getMessage()).toEqual(managedNativeNotification.managedAps.alert);
});
it("should return the sound", () => {
expect(notification.getSound()).to.equal(someSound);
it('should return the sound', () => {
expect(notification.getSound()).toEqual(someSound);
});
it("should return the badge count", () => {
expect(notification.getBadgeCount()).to.equal(someBadgeCount);
it('should return the badge count', () => {
expect(notification.getBadgeCount()).toEqual(someBadgeCount);
});
it("should return the category", () => {
expect(notification.getCategory()).to.equal(someCategory);
it('should return the category', () => {
expect(notification.getCategory()).toEqual(someCategory);
});
it("should return the custom data", () => {
expect(notification.getData()).to.deep.equal({ managedAps: managedNativeNotification.managedAps, key1: "value1", key2: "value2" });
it('should return the custom data', () => {
expect(notification.getData()).toEqual({ managedAps: managedNativeNotification.managedAps, key1: 'value1', key2: 'value2' });
});
});
});
const babelOptions = require('./package.json').babel;
module.exports = function (wallaby) {
return {
env: {
type: 'node',
runner: 'node'
},
testFramework: 'jest',
files: [
'package.json',
'lib/src/**/*.js',
'lib/src/**/*.ts',
'lib/src/**/*.tsx'
],
tests: [
'test/**/*.spec.js'
],
compilers: {
'**/*.js': wallaby.compilers.babel(babelOptions),
'**/*.ts?(x)': wallaby.compilers.typeScript({
module: 'commonjs',
jsx: 'React'
})
},
setup: (w) => {
w.testFramework.configure(require('./package.json').jest);
}
};
};
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