Commit 6a3809ab authored by yogevbd's avatar yogevbd

WIP

parent 10730bed
#import "RNBridgeModule.h" #import "RNBridgeModule.h"
#import "RNCommandsHandler.h" #import "RNCommandsHandler.h"
#import "RCTConvert+Notifications.h" #import "RCTConvert+Notifications.h"
#import "RNNotificationsBridgeQueue.h"
#import "RNEventEmitter.h" #import "RNEventEmitter.h"
#import "RNNotifications.h" #import "RNNotifications.h"
#import "RNNotificationsStore.h"
@implementation RNBridgeModule { @implementation RNBridgeModule {
RNNotificationsStore* _store;
RNCommandsHandler* _commandsHandler; RNCommandsHandler* _commandsHandler;
} }
...@@ -15,6 +16,7 @@ RCT_EXPORT_MODULE(); ...@@ -15,6 +16,7 @@ RCT_EXPORT_MODULE();
- (instancetype)init { - (instancetype)init {
self = [super init]; self = [super init];
_store = [RNNotificationsStore new];
_commandsHandler = [[RNCommandsHandler alloc] init]; _commandsHandler = [[RNCommandsHandler alloc] init];
return self; return self;
} }
...@@ -29,7 +31,7 @@ RCT_EXPORT_MODULE(); ...@@ -29,7 +31,7 @@ RCT_EXPORT_MODULE();
- (void)setBridge:(RCTBridge *)bridge { - (void)setBridge:(RCTBridge *)bridge {
_bridge = bridge; _bridge = bridge;
[RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification = [_bridge.launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; _store.initialNotification = [_bridge.launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
} }
#pragma mark - JS interface #pragma mark - JS interface
......
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <React/RCTBridge.h> #import <React/RCTBridge.h>
#import "RNNotificationsStore.h"
@interface RNCommandsHandler : NSObject @interface RNCommandsHandler : NSObject
- (instancetype)initWithStore:(RNNotificationsStore *)store;
- (void)requestPermissionsWithCategories:(NSArray *)json; - (void)requestPermissionsWithCategories:(NSArray *)json;
- (void)getInitialNotification:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject; - (void)getInitialNotification:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject;
......
#import "RNCommandsHandler.h" #import "RNCommandsHandler.h"
#import "RNNotifications.h" #import "RNNotifications.h"
#import "RNNotificationsBridgeQueue.h"
#import "RCTConvert+Notifications.h" #import "RCTConvert+Notifications.h"
#import "RNPushKit.h" #import "RNPushKit.h"
@implementation RNCommandsHandler { @implementation RNCommandsHandler {
RNPushKit* _pushKit; RNPushKit* _pushKit;
RNNotificationsStore* _store;
} }
- (instancetype)init { - (instancetype)initWithStore:(RNNotificationsStore *)store {
self = [super init]; self = [super init];
[[NSNotificationCenter defaultCenter] addObserver:self _store = store;
selector:@selector(onJavaScriptLoaded)
name:RCTJavaScriptDidLoadNotification
object:nil];
return self;
}
- (void)onJavaScriptLoaded { return self;
// [RNNotificationsBridgeQueue sharedInstance].jsIsReady = YES;
} }
- (void)requestPermissionsWithCategories:(NSArray *)json { - (void)requestPermissionsWithCategories:(NSArray *)json {
...@@ -39,7 +33,9 @@ ...@@ -39,7 +33,9 @@
if (granted) { if (granted) {
[UNUserNotificationCenter.currentNotificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { [UNUserNotificationCenter.currentNotificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) { if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) {
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] registerForRemoteNotifications]; [[UIApplication sharedApplication] registerForRemoteNotifications];
});
} }
}]; }];
} else { } else {
...@@ -50,11 +46,11 @@ ...@@ -50,11 +46,11 @@
} }
- (void)getInitialNotification:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject { - (void)getInitialNotification:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
resolve([RNNotificationsBridgeQueue sharedInstance].openedRemoteNotification); resolve(_store.initialNotification);
} }
- (void)completionHandler:(NSString *)completionKey { - (void)completionHandler:(NSString *)completionKey {
[[RNNotificationsBridgeQueue sharedInstance] completeAction:completionKey]; [_store completeAction:completionKey];
} }
- (void)abandonPermissions { - (void)abandonPermissions {
......
#import "RCTEventEmitter.h" #import "RCTEventEmitter.h"
static NSString* const Registered = @"remoteNotificationsRegistered"; static NSString* const RNRegistered = @"RNNotificationsRegistered";
static NSString* const RegistrationFailed = @"remoteNotificationsRegistrationFailed"; static NSString* const RNRegistrationFailed = @"RNNotificationsRegistrationFailed";
static NSString* const PushKitRegistered = @"pushKitRegistered"; static NSString* const RNPushKitRegistered = @"RNPushKitRegistered";
static NSString* const NotificationReceivedForeground = @"notificationReceivedForeground"; static NSString* const RNNotificationReceivedForeground = @"RNNotificationReceivedForeground";
static NSString* const NotificationReceivedBackground = @"notificationReceivedBackground"; static NSString* const RNNotificationReceivedBackground = @"RNNotificationReceivedBackground";
static NSString* const NotificationOpened = @"notificationOpened"; static NSString* const RNNotificationOpened = @"RNNotificationOpened";
static NSString* const NotificationActionReceived = @"notificationActionReceived"; static NSString* const RNActionTriggered = @"RNNotificationActionTriggered";
@interface RNEventEmitter : RCTEventEmitter @interface RNEventEmitter : RCTEventEmitter
......
...@@ -5,13 +5,13 @@ ...@@ -5,13 +5,13 @@
RCT_EXPORT_MODULE(); RCT_EXPORT_MODULE();
-(NSArray<NSString *> *)supportedEvents { -(NSArray<NSString *> *)supportedEvents {
return @[Registered, return @[RNRegistered,
RegistrationFailed, RNRegistrationFailed,
PushKitRegistered, RNPushKitRegistered,
NotificationReceivedForeground, RNNotificationReceivedForeground,
NotificationReceivedBackground, RNNotificationReceivedBackground,
NotificationOpened, RNNotificationOpened,
NotificationActionReceived]; RNActionTriggered];
} }
# pragma mark public # pragma mark public
......
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@import UserNotifications; @import UserNotifications;
#import "RNNotificationsStore.h"
@interface RNNotificationEventHandler : NSObject @interface RNNotificationEventHandler : NSObject
- (instancetype)initWithStore:(RNNotificationsStore *)store;
- (void)didReceiveForegroundPayload:(NSDictionary *)payload; - (void)didReceiveForegroundPayload:(NSDictionary *)payload;
- (void)didOpenNotificationPayload:(NSDictionary *)payload; - (void)didOpenNotificationPayload:(NSDictionary *)payload;
- (void)handleActionWithIdentifier:(NSString *)identifier forPayload:(NSDictionary *)payload withResponse:(NSString *)response completionHandler:(void (^)())completionHandler; - (void)handleActionWithIdentifier:(NSString *)identifier forPayload:(NSDictionary *)payload withResponse:(NSString *)response completionHandler:(void (^)())completionHandler;
......
#import "RNNotificationEventHandler.h" #import "RNNotificationEventHandler.h"
#import "RNNotificationsBridgeQueue.h"
#import "RNEventEmitter.h" #import "RNEventEmitter.h"
@implementation RNNotificationEventHandler @implementation RNNotificationEventHandler {
RNNotificationsStore* _store;
}
- (instancetype)initWithStore:(RNNotificationsStore *)store {
self = [super init];
_store = store;
return self;
}
- (void)didReceiveForegroundPayload:(NSDictionary *)payload { - (void)didReceiveForegroundPayload:(NSDictionary *)payload {
// if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady == YES) { [RNEventEmitter sendEvent:RNNotificationReceivedForeground body:payload];
[RNEventEmitter sendEvent:NotificationReceivedForeground body:payload];
// }
} }
- (void)didOpenNotificationPayload:(NSDictionary *)payload { - (void)didOpenNotificationPayload:(NSDictionary *)payload {
// if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady == YES) { [RNEventEmitter sendEvent:RNNotificationOpened body:payload];
[RNEventEmitter sendEvent:NotificationOpened body:payload];
// }
} }
- (void)handleActionWithIdentifier:(NSString *)identifier forPayload:(NSDictionary *)payload withResponse:(NSString *)response completionHandler:(void (^)())completionHandler { - (void)handleActionWithIdentifier:(NSString *)identifier forPayload:(NSDictionary *)payload withResponse:(NSString *)response completionHandler:(void (^)())completionHandler {
...@@ -33,12 +37,8 @@ ...@@ -33,12 +37,8 @@
info[@"notification"] = userInfo; 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). [_store setCompletionHandler:completionHandler withCompletionKey:identifier];
[[RNNotificationsBridgeQueue sharedInstance] postAction:info withCompletionKey:completionKey andCompletionHandler:completionHandler]; [RNEventEmitter sendEvent:RNActionTriggered body:userInfo];
// if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady == YES) {
[RNEventEmitter sendEvent:NotificationActionReceived body:userInfo];
// }
} }
@end @end
...@@ -6,17 +6,16 @@ ...@@ -6,17 +6,16 @@
#import "RNNotifications.h" #import "RNNotifications.h"
#import <React/RCTConvert.h> #import <React/RCTConvert.h>
#import <React/RCTUtils.h> #import <React/RCTUtils.h>
#import "RNNotificationsBridgeQueue.h"
#import <UserNotifications/UserNotifications.h> #import <UserNotifications/UserNotifications.h>
#import "RNEventEmitter.h" #import "RNEventEmitter.h"
#import "RNNotificationEventHandler.h" #import "RNNotificationCenterListener.h"
#import "RNUtils.h" #import "RNUtils.h"
NSString* const RNNotificationCreateAction = @"CREATE"; NSString* const RNNotificationCreateAction = @"CREATE";
NSString* const RNNotificationClearAction = @"CLEAR"; NSString* const RNNotificationClearAction = @"CLEAR";
@implementation RNNotifications { @implementation RNNotifications {
RNNotificationEventHandler* _notificationEventHandler; RNNotificationCenterListener* _notificationCenterListener;
} }
+ (instancetype)sharedInstance { + (instancetype)sharedInstance {
...@@ -30,16 +29,17 @@ NSString* const RNNotificationClearAction = @"CLEAR"; ...@@ -30,16 +29,17 @@ NSString* const RNNotificationClearAction = @"CLEAR";
} }
- (void)initialize { - (void)initialize {
_notificationEventHandler = [RNNotificationEventHandler new]; RNNotificationEventHandler* notificationEventHandler = [RNNotificationEventHandler new];
_notificationCenterListener = [[RNNotificationCenterListener alloc] initWithNotificationEventHandler:notificationEventHandler];
} }
- (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken { - (void)didRegisterForRemoteNotificationsWithDeviceToken:(id)deviceToken {
NSString *tokenRepresentation = [deviceToken isKindOfClass:[NSString class]] ? deviceToken : [RNUtils deviceTokenToString:deviceToken]; NSString *tokenRepresentation = [deviceToken isKindOfClass:[NSString class]] ? deviceToken : [RNUtils deviceTokenToString:deviceToken];
[RNEventEmitter sendEvent:Registered body:@{@"deviceToken": tokenRepresentation}]; [RNEventEmitter sendEvent:RNRegistered body:@{@"deviceToken": tokenRepresentation}];
} }
- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { - (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
[RNEventEmitter sendEvent:RegistrationFailed body:@{@"code": [NSNumber numberWithInteger:error.code], @"domain": error.domain, @"localizedDescription": error.localizedDescription}]; [RNEventEmitter sendEvent:RNRegistrationFailed body:@{@"code": [NSNumber numberWithInteger:error.code], @"domain": error.domain, @"localizedDescription": error.localizedDescription}];
} }
- (void)setBadgeForNotification:(NSDictionary *)notification { - (void)setBadgeForNotification:(NSDictionary *)notification {
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
50351F9822CD8604000713B3 /* RNCommandsHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 50351F9722CD8604000713B3 /* RNCommandsHandler.m */; }; 50351F9822CD8604000713B3 /* RNCommandsHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 50351F9722CD8604000713B3 /* RNCommandsHandler.m */; };
507DCCF522CE3EBD005D4E0B /* RNNotifications.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = D8A2F7561CB57F28002CC8F5 /* RNNotifications.h */; }; 507DCCF522CE3EBD005D4E0B /* RNNotifications.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = D8A2F7561CB57F28002CC8F5 /* RNNotifications.h */; };
507DCCF722CE3EF7005D4E0B /* RNBridgeModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 50351F9022CD7DF4000713B3 /* RNBridgeModule.h */; }; 507DCCF722CE3EF7005D4E0B /* RNBridgeModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 50351F9022CD7DF4000713B3 /* RNBridgeModule.h */; };
507DCCF822CE3F04005D4E0B /* RNNotificationsBridgeQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = D85B37461CC05A1200DE9EB6 /* RNNotificationsBridgeQueue.h */; };
507DCCF922CE3F04005D4E0B /* RNNotifications.h in Headers */ = {isa = PBXBuildFile; fileRef = D8A2F7561CB57F28002CC8F5 /* RNNotifications.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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 */; }; 507DCCFA22CE3F04005D4E0B /* RNEventEmitter.h in Headers */ = {isa = PBXBuildFile; fileRef = 50351F8D22CD782F000713B3 /* RNEventEmitter.h */; };
507DCCFB22CE3F04005D4E0B /* RNCommandsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 50351F9622CD8604000713B3 /* RNCommandsHandler.h */; }; 507DCCFB22CE3F04005D4E0B /* RNCommandsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 50351F9622CD8604000713B3 /* RNCommandsHandler.h */; };
...@@ -34,7 +33,6 @@ ...@@ -34,7 +33,6 @@
50AD1FCB22D13ADB00E12362 /* RNPushKitEventHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 50AD1FC922D13ADB00E12362 /* RNPushKitEventHandler.m */; }; 50AD1FCB22D13ADB00E12362 /* RNPushKitEventHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 50AD1FC922D13ADB00E12362 /* RNPushKitEventHandler.m */; };
50E49F0722D1E4E0007160C1 /* RNNotificationsStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E49F0522D1E4E0007160C1 /* RNNotificationsStore.h */; }; 50E49F0722D1E4E0007160C1 /* RNNotificationsStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E49F0522D1E4E0007160C1 /* RNNotificationsStore.h */; };
50E49F0822D1E4E0007160C1 /* RNNotificationsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 50E49F0622D1E4E0007160C1 /* RNNotificationsStore.m */; }; 50E49F0822D1E4E0007160C1 /* RNNotificationsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 50E49F0622D1E4E0007160C1 /* RNNotificationsStore.m */; };
D85B37451CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = D85B37441CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m */; };
D8A2F7551CB57F1A002CC8F5 /* RNNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */; }; D8A2F7551CB57F1A002CC8F5 /* RNNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
...@@ -90,8 +88,6 @@ ...@@ -90,8 +88,6 @@
50AD1FC922D13ADB00E12362 /* RNPushKitEventHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNPushKitEventHandler.m; 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>"; }; 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>"; }; 50E49F0622D1E4E0007160C1 /* RNNotificationsStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNotificationsStore.m; sourceTree = "<group>"; };
D85B37441CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNotificationsBridgeQueue.m; sourceTree = "<group>"; };
D85B37461CC05A1200DE9EB6 /* RNNotificationsBridgeQueue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNotificationsBridgeQueue.h; sourceTree = "<group>"; };
D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNotifications.m; sourceTree = "<group>"; }; D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNotifications.m; sourceTree = "<group>"; };
D8A2F7561CB57F28002CC8F5 /* RNNotifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNotifications.h; sourceTree = "<group>"; }; D8A2F7561CB57F28002CC8F5 /* RNNotifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNotifications.h; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
...@@ -188,8 +184,6 @@ ...@@ -188,8 +184,6 @@
D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */, D8A2F7541CB57F1A002CC8F5 /* RNNotifications.m */,
50E49F0522D1E4E0007160C1 /* RNNotificationsStore.h */, 50E49F0522D1E4E0007160C1 /* RNNotificationsStore.h */,
50E49F0622D1E4E0007160C1 /* RNNotificationsStore.m */, 50E49F0622D1E4E0007160C1 /* RNNotificationsStore.m */,
D85B37461CC05A1200DE9EB6 /* RNNotificationsBridgeQueue.h */,
D85B37441CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m */,
50351F8D22CD782F000713B3 /* RNEventEmitter.h */, 50351F8D22CD782F000713B3 /* RNEventEmitter.h */,
50351F8E22CD782F000713B3 /* RNEventEmitter.m */, 50351F8E22CD782F000713B3 /* RNEventEmitter.m */,
50351F9322CD7FF1000713B3 /* RCTConvert+Notifications.h */, 50351F9322CD7FF1000713B3 /* RCTConvert+Notifications.h */,
...@@ -215,7 +209,6 @@ ...@@ -215,7 +209,6 @@
508CE81922D130B900357815 /* RNPushKitEventListener.h in Headers */, 508CE81922D130B900357815 /* RNPushKitEventListener.h in Headers */,
50E49F0722D1E4E0007160C1 /* RNNotificationsStore.h in Headers */, 50E49F0722D1E4E0007160C1 /* RNNotificationsStore.h in Headers */,
508CE81622D12FF600357815 /* RNNotificationCenterListener.h in Headers */, 508CE81622D12FF600357815 /* RNNotificationCenterListener.h in Headers */,
507DCCF822CE3F04005D4E0B /* RNNotificationsBridgeQueue.h in Headers */,
508CE82222D1372E00357815 /* RNUtils.h in Headers */, 508CE82222D1372E00357815 /* RNUtils.h in Headers */,
507DCCFA22CE3F04005D4E0B /* RNEventEmitter.h in Headers */, 507DCCFA22CE3F04005D4E0B /* RNEventEmitter.h in Headers */,
507DCCFB22CE3F04005D4E0B /* RNCommandsHandler.h in Headers */, 507DCCFB22CE3F04005D4E0B /* RNCommandsHandler.h in Headers */,
...@@ -328,7 +321,6 @@ ...@@ -328,7 +321,6 @@
508CE81A22D130B900357815 /* RNPushKitEventListener.m in Sources */, 508CE81A22D130B900357815 /* RNPushKitEventListener.m in Sources */,
50351F9222CD7DF4000713B3 /* RNBridgeModule.m in Sources */, 50351F9222CD7DF4000713B3 /* RNBridgeModule.m in Sources */,
508CE81E22D1337200357815 /* RNPushKit.m in Sources */, 508CE81E22D1337200357815 /* RNPushKit.m in Sources */,
D85B37451CC05A0900DE9EB6 /* RNNotificationsBridgeQueue.m in Sources */,
508CE7D622D12CCA00357815 /* RNNotificationEventHandler.m in Sources */, 508CE7D622D12CCA00357815 /* RNNotificationEventHandler.m in Sources */,
50E49F0822D1E4E0007160C1 /* RNNotificationsStore.m in Sources */, 50E49F0822D1E4E0007160C1 /* RNNotificationsStore.m in Sources */,
508CE82322D1372E00357815 /* RNUtils.m in Sources */, 508CE82322D1372E00357815 /* RNUtils.m in Sources */,
......
#import <Foundation/Foundation.h>
@interface RNNotificationsBridgeQueue : NSObject
@property NSDictionary* openedRemoteNotification;
+ (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
#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];
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
...@@ -2,4 +2,9 @@ ...@@ -2,4 +2,9 @@
@interface RNNotificationsStore : NSObject @interface RNNotificationsStore : NSObject
@property NSDictionary* initialNotification;
- (void)completeAction:(NSString *)completionKey;
- (void)setCompletionHandler:(void (^)())completionHandler withCompletionKey:(NSString *)completionKey;
@end @end
#import "RNNotificationsStore.h" #import "RNNotificationsStore.h"
@implementation RNNotificationsStore { @implementation RNNotificationsStore {
NSMutableDictionary* actionCompletionHandlers; NSMutableDictionary* _actionCompletionHandlers;
} }
- (instancetype)init { - (instancetype)init {
actionCompletionHandlers = [NSMutableDictionary new]; self = [super init];
_actionCompletionHandlers = [NSMutableDictionary new];
return self; return self;
} }
- (void)setCompletionHandler:(void (^)())completionHandler withCompletionKey:(NSString *)completionKey {
_actionCompletionHandlers[completionKey] = completionHandler;
}
- (void)completeAction:(NSString *)completionKey {
void (^completionHandler)() = (void (^)())[_actionCompletionHandlers valueForKey:completionKey];
if (completionHandler) {
completionHandler();
[_actionCompletionHandlers removeObjectForKey:completionKey];
}
}
@end @end
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
@implementation RNPushKitEventHandler @implementation RNPushKitEventHandler
- (void)registeredWithToken:(NSString *)token { - (void)registeredWithToken:(NSString *)token {
[RNEventEmitter sendEvent:PushKitRegistered body:@{@"pushKitToken": token}]; [RNEventEmitter sendEvent:RNPushKitRegistered body:@{@"pushKitToken": token}];
} }
@end @end
const Utils = require('./Utils');
const { elementByLabel, elementById, sleep } = Utils;
describe('BottomTabs', () => {
beforeEach(async () => {
await device.relaunchApp();
// await elementById(TestIDs.BOTTOM_TABS_BTN).tap();
// await expect(elementByLabel('First Tab')).toBeVisible();
});
it('switch to tab by index', async () => {
// await elementById(TestIDs.SWITCH_TAB_BY_INDEX_BTN).tap();
await expect(elementByLabel('First Tab')).toBeNotVisible();
await expect(elementByLabel('Second Tab')).toBeVisible();
});
});
const Utils = require('./Utils');
const { elementByLabel, elementById } = Utils;
describe('Notifications', () => {
beforeEach(async () => {
await device.relaunchApp({permissions: {notifications: 'YES'}});
});
it('Receive foreground notification', async () => {
await device.sendUserNotification(getNotification('explicit/external/link/test_parameter'));
// await device.launchApp({newInstance: true, userNotification: getNotification('unknown/link', 'test/category', {parameter: 'test_body_param'})});
// await elementById(TestIDs.SWITCH_TAB_BY_INDEX_BTN).tap();
// await expect(elementByLabel('First Tab')).toBeNotVisible();
// await expect(elementByLabel('Second Tab')).toBeVisible();
});
});
function getNotification(link, category = 'com.example.category', params = {}) {
return {
trigger: {
type: 'push'
},
title: 'From push',
subtitle: 'Subtitle',
body: 'Body',
badge: 1,
payload: {
appId: '14517e1a-3ff0-af98-408e-2bd6953c36a2',
aps: {
alert: 'this is alert',
sound: 'chime.aiff'
},
category,
link, ...params
},
'content-available': 0,
'action-identifier': 'default'
};
}
\ No newline at end of file
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
import { import {
AppRegistry, AppRegistry,
StyleSheet, StyleSheet,
View, View,
Text Text,
Button
} from 'react-native'; } from 'react-native';
import React, {Component} from 'react'; import React, {Component} from 'react';
...@@ -37,18 +33,15 @@ let replyAction = new NotificationAction({ ...@@ -37,18 +33,15 @@ let replyAction = new NotificationAction({
completed(); completed();
}); });
let cat = new NotificationCategory({
identifier: 'SOME_CATEGORY',
actions: [upvoteAction, replyAction],
context: 'default'
});
class NotificationsExampleApp extends Component { class NotificationsExampleApp extends Component {
constructor() { constructor() {
super(); super();
this.state = {
notifications: []
};
NotificationsIOS.addEventListener('remoteNotificationsRegistered', this.onPushRegistered.bind(this)); NotificationsIOS.addEventListener('remoteNotificationsRegistered', this.onPushRegistered.bind(this));
NotificationsIOS.requestPermissions([cat]);
NotificationsIOS.consumeBackgroundQueue(); NotificationsIOS.consumeBackgroundQueue();
...@@ -56,7 +49,6 @@ class NotificationsExampleApp extends Component { ...@@ -56,7 +49,6 @@ class NotificationsExampleApp extends Component {
NotificationsIOS.registerPushKit(); NotificationsIOS.registerPushKit();
NotificationsIOS.addEventListener('notificationReceivedForeground', this.onNotificationReceivedForeground.bind(this)); NotificationsIOS.addEventListener('notificationReceivedForeground', this.onNotificationReceivedForeground.bind(this));
NotificationsIOS.addEventListener('notificationReceivedBackground', this.onNotificationReceivedBackground.bind(this));
NotificationsIOS.addEventListener('notificationOpened', this.onNotificationOpened.bind(this)); NotificationsIOS.addEventListener('notificationOpened', this.onNotificationOpened.bind(this));
} }
...@@ -69,54 +61,48 @@ class NotificationsExampleApp extends Component { ...@@ -69,54 +61,48 @@ class NotificationsExampleApp extends Component {
} }
onNotificationReceivedForeground(notification) { onNotificationReceivedForeground(notification) {
alert(JSON.stringify(notification));
console.log('Notification Received Foreground: ' + JSON.stringify(notification)); console.log('Notification Received Foreground: ' + JSON.stringify(notification));
} this.setState({
notifications: [...this.state.notifications, notification]
onNotificationReceivedBackground(notification) {
NotificationsIOS.log('Notification Received Background: ' + 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()
}); });
// 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));
// NotificationsIOS.cancelLocalNotification(localNotification);
} }
onNotificationOpened(notification) { onNotificationOpened(notification) {
console.log('Notification Opened: ' + JSON.stringify(notification)); console.log('Notification Opened: ' + JSON.stringify(notification));
} }
renderNotification(notification) {
return <Text>{`${''} | ${JSON.stringify(notification)}`}</Text>;
}
render() { render() {
const notifications = this.state.notifications.map((notification, idx) =>
(
<View key={`notification_${idx}`}>
{this.renderNotification(notification)}
</View>
));
return ( return (
<View style={styles.container}> <View style={styles.container}>
<Text style={styles.welcome}> <Button title={'Request permissions'} onPress={this.requestPermissions} testID={'requestPermissions'}/>
Welcome to React Native Notifications Demo App! {notifications}
</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>
</View> </View>
); );
} }
requestPermissions() {
let cat = new NotificationCategory({
identifier: 'SOME_CATEGORY',
actions: [upvoteAction, replyAction],
context: 'default'
});
NotificationsIOS.requestPermissions([cat]);
}
componentWillUnmount() { componentWillUnmount() {
NotificationsIOS.removeEventListener('notificationReceivedForeground', this.onNotificationReceivedForeground.bind(this)); NotificationsIOS.removeEventListener('notificationReceivedForeground', this.onNotificationReceivedForeground.bind(this));
NotificationsIOS.removeEventListener('notificationReceivedBackground', this.onNotificationReceivedBackground.bind(this));
NotificationsIOS.removeEventListener('notificationOpened', this.onNotificationOpened.bind(this)); NotificationsIOS.removeEventListener('notificationOpened', this.onNotificationOpened.bind(this));
NotificationsIOS.removeEventListener('remoteNotificationsRegistered', this.onPushRegistered.bind(this)); NotificationsIOS.removeEventListener('remoteNotificationsRegistered', this.onPushRegistered.bind(this));
NotificationsIOS.removeEventListener('pushKitRegistered', this.onPushKitRegistered.bind(this)); NotificationsIOS.removeEventListener('pushKitRegistered', this.onPushKitRegistered.bind(this));
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
50F1F0CC22CE3B4700FD5829 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F06022CE3A6100FD5829 /* libReact.a */; }; 50F1F0CC22CE3B4700FD5829 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F06022CE3A6100FD5829 /* libReact.a */; };
50F1F0CD22CE3B6300FD5829 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F08A22CE3AA000FD5829 /* libRCTActionSheet.a */; }; 50F1F0CD22CE3B6300FD5829 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F08A22CE3AA000FD5829 /* libRCTActionSheet.a */; };
50F1F0CE22CE3B6300FD5829 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F08F22CE3AB200FD5829 /* libRCTGeolocation.a */; };
50F1F0CF22CE3B6300FD5829 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F09522CE3ABE00FD5829 /* libRCTImage.a */; }; 50F1F0CF22CE3B6300FD5829 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F09522CE3ABE00FD5829 /* libRCTImage.a */; };
50F1F0D022CE3B6300FD5829 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F09D22CE3ACA00FD5829 /* libRCTLinking.a */; }; 50F1F0D022CE3B6300FD5829 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F09D22CE3ACA00FD5829 /* libRCTLinking.a */; };
50F1F0D122CE3B6300FD5829 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F0A622CE3B0600FD5829 /* libRCTNetwork.a */; }; 50F1F0D122CE3B6300FD5829 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 50F1F0A622CE3B0600FD5829 /* libRCTNetwork.a */; };
...@@ -154,13 +153,6 @@ ...@@ -154,13 +153,6 @@
remoteGlobalIDString = 134814201AA4EA6300B7C361; remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTActionSheet; remoteInfo = RCTActionSheet;
}; };
50F1F08E22CE3AB200FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTGeolocation;
};
50F1F09422CE3ABE00FD5829 /* PBXContainerItemProxy */ = { 50F1F09422CE3ABE00FD5829 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
...@@ -277,7 +269,6 @@ ...@@ -277,7 +269,6 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; }; 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; 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>"; }; 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>"; }; 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>"; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
...@@ -308,7 +299,6 @@ ...@@ -308,7 +299,6 @@
50F1F0D722CE3C1E00FD5829 /* libcxxreact.a in Frameworks */, 50F1F0D722CE3C1E00FD5829 /* libcxxreact.a in Frameworks */,
50F1F0D622CE3C0F00FD5829 /* libyoga.a in Frameworks */, 50F1F0D622CE3C0F00FD5829 /* libyoga.a in Frameworks */,
50F1F0CD22CE3B6300FD5829 /* libRCTActionSheet.a in Frameworks */, 50F1F0CD22CE3B6300FD5829 /* libRCTActionSheet.a in Frameworks */,
50F1F0CE22CE3B6300FD5829 /* libRCTGeolocation.a in Frameworks */,
50F1F0CF22CE3B6300FD5829 /* libRCTImage.a in Frameworks */, 50F1F0CF22CE3B6300FD5829 /* libRCTImage.a in Frameworks */,
50F1F0D022CE3B6300FD5829 /* libRCTLinking.a in Frameworks */, 50F1F0D022CE3B6300FD5829 /* libRCTLinking.a in Frameworks */,
50F1F0D122CE3B6300FD5829 /* libRCTNetwork.a in Frameworks */, 50F1F0D122CE3B6300FD5829 /* libRCTNetwork.a in Frameworks */,
...@@ -387,14 +377,6 @@ ...@@ -387,14 +377,6 @@
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
50F1F08B22CE3AB200FD5829 /* Products */ = {
isa = PBXGroup;
children = (
50F1F08F22CE3AB200FD5829 /* libRCTGeolocation.a */,
);
name = Products;
sourceTree = "<group>";
};
50F1F09022CE3ABE00FD5829 /* Products */ = { 50F1F09022CE3ABE00FD5829 /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
...@@ -466,7 +448,6 @@ ...@@ -466,7 +448,6 @@
D85498C21D97B31100DEEE06 /* RNNotifications.xcodeproj */, D85498C21D97B31100DEEE06 /* RNNotifications.xcodeproj */,
146833FF1AC3E56700842450 /* React.xcodeproj */, 146833FF1AC3E56700842450 /* React.xcodeproj */,
50F1F08522CE3A9F00FD5829 /* RCTActionSheet.xcodeproj */, 50F1F08522CE3A9F00FD5829 /* RCTActionSheet.xcodeproj */,
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */,
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */,
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */,
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */, 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */,
...@@ -561,10 +542,6 @@ ...@@ -561,10 +542,6 @@
ProductGroup = 50F1F08622CE3A9F00FD5829 /* Products */; ProductGroup = 50F1F08622CE3A9F00FD5829 /* Products */;
ProjectRef = 50F1F08522CE3A9F00FD5829 /* RCTActionSheet.xcodeproj */; ProjectRef = 50F1F08522CE3A9F00FD5829 /* RCTActionSheet.xcodeproj */;
}, },
{
ProductGroup = 50F1F08B22CE3AB200FD5829 /* Products */;
ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
},
{ {
ProductGroup = 50F1F09022CE3ABE00FD5829 /* Products */; ProductGroup = 50F1F09022CE3ABE00FD5829 /* Products */;
ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
...@@ -736,13 +713,6 @@ ...@@ -736,13 +713,6 @@
remoteRef = 50F1F08922CE3AA000FD5829 /* PBXContainerItemProxy */; remoteRef = 50F1F08922CE3AA000FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR; sourceTree = BUILT_PRODUCTS_DIR;
}; };
50F1F08F22CE3AB200FD5829 /* libRCTGeolocation.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTGeolocation.a;
remoteRef = 50F1F08E22CE3AB200FD5829 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
50F1F09522CE3ABE00FD5829 /* libRCTImage.a */ = { 50F1F09522CE3ABE00FD5829 /* libRCTImage.a */ = {
isa = PBXReferenceProxy; isa = PBXReferenceProxy;
fileType = archive.ar; fileType = archive.ar;
......
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