Skip to content

Commit 0e2d4de

Browse files
committed
ios: queuing batch dispatched events when module is not ready
1 parent 9044b76 commit 0e2d4de

File tree

5 files changed

+178
-82
lines changed

5 files changed

+178
-82
lines changed

ios/RNBatch.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
#define PluginVersion "ReactNative/8.1.0"
1616

17-
@interface RNBatch : RCTEventEmitter <RCTBridgeModule, BatchEventDispatcherDelegate>
17+
@interface RNBatch : RCTEventEmitter <RCTBridgeModule>
1818

1919
+ (void)start;
2020

ios/RNBatch.m

+29-81
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# import <React/RCTConvert.h>
22
# import "RNBatch.h"
33
# import "RNBatchOpenedNotificationObserver.h"
4+
# import "RNBatchEventDispatcher.h"
5+
6+
static RNBatchEventDispatcher* dispatcher = nil;
47

58
@implementation RNBatch
6-
{
7-
bool hasListeners;
8-
}
99

1010
+ (BOOL)requiresMainQueueSetup
1111
{
@@ -27,7 +27,7 @@ - (instancetype)init
2727
{
2828
self = [super init];
2929
_batchInboxFetcherMap = [NSMutableDictionary new];
30-
[BatchEventDispatcher addDispatcher:self];
30+
[dispatcher setModuleIsReady:true];
3131
return self;
3232
}
3333

@@ -48,6 +48,31 @@ + (void)start
4848

4949
NSString *batchAPIKey = [info objectForKey:@"BatchAPIKey"];
5050
[Batch startWithAPIKey:batchAPIKey];
51+
dispatcher = [[RNBatchEventDispatcher alloc] init];
52+
[BatchEventDispatcher addDispatcher:dispatcher];
53+
}
54+
55+
-(void)startObserving {
56+
[dispatcher setSendBlock:^(RNBatchEvent* event) {
57+
[self sendEventWithName:event.name body:event.body];
58+
}];
59+
}
60+
61+
-(void)stopObserving {
62+
[dispatcher setSendBlock:nil];
63+
}
64+
65+
- (NSArray<NSString *> *)supportedEvents {
66+
NSMutableArray *events = [NSMutableArray new];
67+
68+
for (int i = BatchEventDispatcherTypeNotificationOpen; i <= BatchEventDispatcherTypeMessagingWebViewClick; i++) {
69+
NSString* eventName = [RNBatchEventDispatcher mapBatchEventDispatcherTypeToRNEvent:i];
70+
if (eventName != nil) {
71+
[events addObject:eventName];
72+
}
73+
}
74+
75+
return events;
5176
}
5277

5378
RCT_EXPORT_METHOD(optIn:(RCTPromiseResolveBlock)resolve
@@ -82,83 +107,6 @@ + (void)start
82107
});
83108
}
84109

85-
// Event Dispatcher
86-
87-
-(void)startObserving {
88-
hasListeners = YES;
89-
}
90-
91-
-(void)stopObserving {
92-
hasListeners = NO;
93-
}
94-
95-
- (NSArray<NSString *> *)supportedEvents {
96-
NSMutableArray *events = [NSMutableArray new];
97-
98-
for (int i = BatchEventDispatcherTypeNotificationOpen; i <= BatchEventDispatcherTypeMessagingWebViewClick; i++) {
99-
NSString* eventName = [self mapBatchEventDispatcherTypeToRNEvent:i];
100-
if (eventName != nil) {
101-
[events addObject:eventName];
102-
}
103-
}
104-
105-
return events;
106-
}
107-
108-
- (void)dispatchEventWithType:(BatchEventDispatcherType)type
109-
payload:(nonnull id<BatchEventDispatcherPayload>)payload {
110-
if (hasListeners) {
111-
NSString* eventName = [self mapBatchEventDispatcherTypeToRNEvent:type];
112-
if (eventName != nil) {
113-
[self sendEventWithName:eventName body:[self dictionaryWithEventDispatcherPayload:payload]];
114-
}
115-
}
116-
}
117-
118-
- (nullable NSString *) mapBatchEventDispatcherTypeToRNEvent:(BatchEventDispatcherType)type {
119-
switch (type) {
120-
case BatchEventDispatcherTypeNotificationOpen:
121-
return @"notification_open";
122-
case BatchEventDispatcherTypeMessagingShow:
123-
return @"messaging_show";
124-
case BatchEventDispatcherTypeMessagingClose:
125-
return @"messaging_close";
126-
case BatchEventDispatcherTypeMessagingCloseError:
127-
return @"messaging_close_error";
128-
case BatchEventDispatcherTypeMessagingAutoClose:
129-
return @"messaging_auto_close";
130-
case BatchEventDispatcherTypeMessagingClick:
131-
return @"messaging_click";
132-
case BatchEventDispatcherTypeMessagingWebViewClick:
133-
return @"messaging_webview_click";
134-
}
135-
}
136-
137-
- (NSDictionary*) dictionaryWithEventDispatcherPayload:(id<BatchEventDispatcherPayload>)payload
138-
{
139-
NSMutableDictionary *output = [NSMutableDictionary dictionaryWithDictionary:@{
140-
@"isPositiveAction": @(payload.isPositiveAction),
141-
}];
142-
143-
if (payload.deeplink != nil) {
144-
output[@"deeplink"] = payload.deeplink;
145-
}
146-
147-
if (payload.trackingId != nil) {
148-
output[@"trackingId"] = payload.trackingId;
149-
}
150-
151-
if (payload.deeplink != nil) {
152-
output[@"webViewAnalyticsIdentifier"] = payload.webViewAnalyticsIdentifier;
153-
}
154-
155-
if (payload.notificationUserInfo != nil) {
156-
output[@"pushPayload"] = payload.notificationUserInfo;
157-
}
158-
159-
return output;
160-
}
161-
162110
// Push Module
163111

164112
RCT_EXPORT_METHOD(push_registerForRemoteNotifications)

ios/RNBatchEventDispatcher.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# import "RNBatch.h"
2+
3+
@interface RNBatchEvent : NSObject
4+
5+
@property (readonly) NSString* _Nonnull name;
6+
7+
@property (readonly) NSDictionary* _Nonnull body;
8+
9+
- (nonnull instancetype)initWithName:(nonnull NSString *)name andBody:(nullable NSDictionary *)body;
10+
11+
@end
12+
13+
@interface RNBatchEventDispatcher : NSObject <BatchEventDispatcherDelegate>
14+
15+
- (void)setSendBlock:(void (^_Nullable)(RNBatchEvent* _Nonnull event))callback;
16+
17+
- (void)setModuleIsReady:(BOOL)ready;
18+
19+
+ (nullable NSString *)mapBatchEventDispatcherTypeToRNEvent:(BatchEventDispatcherType)type;
20+
21+
@end

ios/RNBatchEventDispatcher.m

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# import "RNBatchEventDispatcher.h"
2+
3+
@implementation RNBatchEventDispatcher {
4+
5+
BOOL _moduleIsReady;
6+
7+
NSMutableArray<RNBatchEvent*>* _events;
8+
9+
void (^_sendBlock)(RNBatchEvent *_Nonnull event);
10+
}
11+
12+
-(instancetype)init {
13+
self = [super init];
14+
if (self) {
15+
_events = [NSMutableArray array];
16+
}
17+
return self;
18+
}
19+
20+
-(void)setSendBlock:(void (^)(RNBatchEvent* event))callback {
21+
_sendBlock = callback;
22+
if(_sendBlock != nil) {
23+
[self dequeueEvents];
24+
}
25+
}
26+
27+
- (void)setModuleIsReady:(BOOL)ready {
28+
_moduleIsReady = ready;
29+
}
30+
31+
32+
- (void)dequeueEvents {
33+
if(_sendBlock == nil) {
34+
return;
35+
}
36+
@synchronized(_events) {
37+
NSArray *enqueuedEvents = [_events copy];
38+
[_events removeAllObjects];
39+
40+
for (RNBatchEvent *event in enqueuedEvents) {
41+
_sendBlock(event);
42+
}
43+
}
44+
}
45+
46+
- (void)dispatchEventWithType:(BatchEventDispatcherType)type
47+
payload:(nonnull id<BatchEventDispatcherPayload>)payload {
48+
49+
if (_moduleIsReady && _sendBlock == nil) {
50+
// RN Module is ready but no listener registered
51+
// not queuing up events
52+
return;
53+
}
54+
NSString* eventName = [RNBatchEventDispatcher mapBatchEventDispatcherTypeToRNEvent:type];
55+
if (eventName != nil) {
56+
RNBatchEvent* event = [[RNBatchEvent alloc] initWithName:eventName andBody:[self dictionaryWithEventDispatcherPayload:payload]];
57+
@synchronized(_events) {
58+
[_events addObject:event];
59+
}
60+
if (_sendBlock != nil) {
61+
[self dequeueEvents];
62+
}
63+
}
64+
}
65+
66+
+ (nullable NSString *) mapBatchEventDispatcherTypeToRNEvent:(BatchEventDispatcherType)type {
67+
switch (type) {
68+
case BatchEventDispatcherTypeNotificationOpen:
69+
return @"notification_open";
70+
case BatchEventDispatcherTypeMessagingShow:
71+
return @"messaging_show";
72+
case BatchEventDispatcherTypeMessagingClose:
73+
return @"messaging_close";
74+
case BatchEventDispatcherTypeMessagingCloseError:
75+
return @"messaging_close_error";
76+
case BatchEventDispatcherTypeMessagingAutoClose:
77+
return @"messaging_auto_close";
78+
case BatchEventDispatcherTypeMessagingClick:
79+
return @"messaging_click";
80+
case BatchEventDispatcherTypeMessagingWebViewClick:
81+
return @"messaging_webview_click";
82+
}
83+
}
84+
85+
- (NSDictionary*) dictionaryWithEventDispatcherPayload:(id<BatchEventDispatcherPayload>)payload
86+
{
87+
NSMutableDictionary *output = [NSMutableDictionary dictionaryWithDictionary:@{
88+
@"isPositiveAction": @(payload.isPositiveAction),
89+
}];
90+
91+
if (payload.deeplink != nil) {
92+
output[@"deeplink"] = payload.deeplink;
93+
}
94+
95+
if (payload.trackingId != nil) {
96+
output[@"trackingId"] = payload.trackingId;
97+
}
98+
99+
if (payload.deeplink != nil) {
100+
output[@"webViewAnalyticsIdentifier"] = payload.webViewAnalyticsIdentifier;
101+
}
102+
103+
if (payload.notificationUserInfo != nil) {
104+
output[@"pushPayload"] = payload.notificationUserInfo;
105+
}
106+
107+
return output;
108+
}
109+
110+
@end
111+
112+
@implementation RNBatchEvent
113+
114+
- (nonnull instancetype)initWithName:(nonnull NSString *)name andBody:(nullable NSDictionary *)body {
115+
self = [super init];
116+
if (self) {
117+
_name = name;
118+
_body = body;
119+
}
120+
return self;
121+
}
122+
123+
@end

ios/RNBatchPush.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
1E4AD39B28EF23220095227A /* RNBatchEventDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E4AD39A28EF23220095227A /* RNBatchEventDispatcher.m */; };
1011
AA04798A214AA8EA0049BDB2 /* RNBatch.m in Sources */ = {isa = PBXBuildFile; fileRef = AA047989214AA8EA0049BDB2 /* RNBatch.m */; };
1112
/* End PBXBuildFile section */
1213

@@ -24,6 +25,7 @@
2425

2526
/* Begin PBXFileReference section */
2627
134814201AA4EA6300B7C361 /* libRNBatchPush.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNBatchPush.a; sourceTree = BUILT_PRODUCTS_DIR; };
28+
1E4AD39A28EF23220095227A /* RNBatchEventDispatcher.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNBatchEventDispatcher.m; sourceTree = "<group>"; };
2729
AA047989214AA8EA0049BDB2 /* RNBatch.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNBatch.m; sourceTree = "<group>"; };
2830
AA04798B214AA8FF0049BDB2 /* RNBatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNBatch.h; sourceTree = "<group>"; };
2931
/* End PBXFileReference section */
@@ -50,6 +52,7 @@
5052
58B511D21A9E6C8500147676 = {
5153
isa = PBXGroup;
5254
children = (
55+
1E4AD39A28EF23220095227A /* RNBatchEventDispatcher.m */,
5356
AA04798B214AA8FF0049BDB2 /* RNBatch.h */,
5457
AA047989214AA8EA0049BDB2 /* RNBatch.m */,
5558
134814211AA4EA7D00B7C361 /* Products */,
@@ -113,6 +116,7 @@
113116
isa = PBXSourcesBuildPhase;
114117
buildActionMask = 2147483647;
115118
files = (
119+
1E4AD39B28EF23220095227A /* RNBatchEventDispatcher.m in Sources */,
116120
AA04798A214AA8EA0049BDB2 /* RNBatch.m in Sources */,
117121
);
118122
runOnlyForDeploymentPostprocessing = 0;

0 commit comments

Comments
 (0)