@sentiance-react-native/core 6.3.0-rc.1 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -563,14 +563,20 @@ public class SentianceModule extends AbstractSentianceModule {
563
563
  promise.resolve(args);
564
564
  }
565
565
 
566
+ @Override
566
567
  @ReactMethod
567
- public void addListener(String eventName) {
568
- // Set up any upstream listeners or background tasks as necessary
568
+ protected void addListener(String eventName, int subscriptionId, Promise promise) {
569
+
569
570
  }
570
571
 
572
+ @Override
571
573
  @ReactMethod
572
- public void removeListeners(Integer count) {
573
- // Remove upstream listeners, stop unnecessary background tasks
574
+ protected void removeListener(String eventName, int subscriptionId, Promise promise) {
575
+
574
576
  }
577
+
578
+ @Override
579
+ @ReactMethod
580
+ public void removeListeners(Integer count) {}
575
581
  }
576
582
 
@@ -2,9 +2,13 @@ package com.sentiance.react.bridge.core.base;
2
2
 
3
3
  import static com.sentiance.react.bridge.core.utils.ErrorCodes.E_SDK_NOT_INITIALIZED;
4
4
 
5
+ import androidx.annotation.NonNull;
6
+
5
7
  import com.facebook.react.bridge.Promise;
6
8
  import com.facebook.react.bridge.ReactApplicationContext;
7
9
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
10
+ import com.facebook.react.bridge.ReactMethod;
11
+ import com.sentiance.react.bridge.core.common.SentianceSubscriptionsManager;
8
12
  import com.sentiance.sdk.InitState;
9
13
  import com.sentiance.sdk.Sentiance;
10
14
 
@@ -12,11 +16,18 @@ public abstract class AbstractSentianceModule extends ReactContextBaseJavaModule
12
16
 
13
17
  protected final ReactApplicationContext reactContext;
14
18
  protected final Sentiance sdk;
19
+ protected final SentianceSubscriptionsManager subscriptionsManager;
15
20
 
16
21
  public AbstractSentianceModule(ReactApplicationContext reactApplicationContext) {
17
22
  super(reactApplicationContext);
18
23
  reactContext = reactApplicationContext;
19
24
  sdk = Sentiance.getInstance(reactContext);
25
+ subscriptionsManager = new SentianceSubscriptionsManager();
26
+ }
27
+
28
+ @Override
29
+ public void initialize() {
30
+ addSupportedEventSubscriptions(subscriptionsManager);
20
31
  }
21
32
 
22
33
  protected boolean rejectIfNotInitialized(Promise promise) {
@@ -30,4 +41,22 @@ public abstract class AbstractSentianceModule extends ReactContextBaseJavaModule
30
41
  private boolean isSdkInitialized() {
31
42
  return sdk.getInitState() == InitState.INITIALIZED;
32
43
  }
44
+
45
+ protected void addSupportedEventSubscriptions(SentianceSubscriptionsManager subscriptionsManager) {
46
+
47
+ }
48
+
49
+ protected <T> void addSubscription(@NonNull String eventType, int subscriptionId, @NonNull T eventEmitterLogic) {
50
+ subscriptionsManager.addSubscription(eventType, subscriptionId, eventEmitterLogic);
51
+ }
52
+
53
+ protected <T> void removeSubscription(int subscriptionId, @NonNull String eventType) {
54
+ subscriptionsManager.removeSubscription(subscriptionId, eventType);
55
+ }
56
+
57
+ protected abstract void removeListener(String eventName, int subscriptionId, Promise promise);
58
+
59
+ protected abstract void addListener(String eventName, int subscriptionId, Promise promise);
60
+
61
+ protected abstract void removeListeners(Integer count);
33
62
  }
@@ -0,0 +1,202 @@
1
+ package com.sentiance.react.bridge.core.common;
2
+
3
+ import androidx.annotation.NonNull;
4
+ import androidx.annotation.Nullable;
5
+
6
+ import com.sentiance.react.bridge.core.utils.SingleParamRunnable;
7
+
8
+ import java.util.ArrayList;
9
+ import java.util.HashMap;
10
+ import java.util.List;
11
+ import java.util.Map;
12
+ import java.util.Objects;
13
+
14
+ @SuppressWarnings("rawtypes")
15
+ public class SentianceSubscriptionsManager {
16
+
17
+ private final List<Subscription> mSubscriptions;
18
+ private final Map<String, SubscriptionDefinition> mSupportedSubscriptions;
19
+
20
+ public SentianceSubscriptionsManager() {
21
+ mSubscriptions = new ArrayList<>();
22
+ mSupportedSubscriptions = new HashMap<>();
23
+ }
24
+
25
+ public <T> void addSupportedSubscription(String eventType, SingleParamRunnable<T> nativeSubscribeLogic,
26
+ SingleParamRunnable<T> nativeUnsubscribeLogic, SubscriptionType subscriptionType) {
27
+ if (mSupportedSubscriptions.containsKey(eventType)) {
28
+ throw new IllegalArgumentException(String.format("A subscription definition for %s has already been added.",
29
+ eventType));
30
+ }
31
+
32
+ mSupportedSubscriptions.put(eventType, new SubscriptionDefinition<>(eventType, nativeSubscribeLogic,
33
+ nativeUnsubscribeLogic, subscriptionType));
34
+ }
35
+
36
+ public <T> void addSubscription(@NonNull String eventType, int subscriptionId, @NonNull T eventEmitterLogic) {
37
+ SubscriptionDefinition definition = mSupportedSubscriptions.get(eventType);
38
+ if (definition == null) {
39
+ return;
40
+ }
41
+
42
+ if (shouldSubscribeNatively(definition)) {
43
+ //noinspection unchecked
44
+ definition.nativeSubscribeLogic.run(eventEmitterLogic);
45
+ }
46
+
47
+ Subscription<T> subscription = new Subscription<>(subscriptionId, eventEmitterLogic, eventType);
48
+
49
+ synchronized (mSubscriptions) {
50
+ mSubscriptions.add(subscription);
51
+ }
52
+ }
53
+
54
+ public void removeSubscription(int subscriptionId, String eventType) {
55
+ SubscriptionDefinition definition = mSupportedSubscriptions.get(eventType);
56
+ if (definition == null) {
57
+ return;
58
+ }
59
+
60
+ Subscription subscription = getExistingSubscription(subscriptionId, eventType);
61
+ if (subscription != null) {
62
+ synchronized (mSubscriptions) {
63
+ mSubscriptions.remove(subscription);
64
+ }
65
+
66
+ if (shouldUnsubscribeNatively(definition)) {
67
+ //noinspection unchecked
68
+ definition.nativeUnsubscribeLogic.run(subscription.eventEmitterLogic);
69
+ }
70
+ }
71
+ }
72
+
73
+ @Nullable
74
+ private Subscription getExistingSubscription(int subscriptionId, String eventType) {
75
+ synchronized (mSubscriptions) {
76
+ for (Subscription subscription : mSubscriptions) {
77
+ if (subscription.id == subscriptionId && subscription.eventType.equals(eventType)) {
78
+ return subscription;
79
+ }
80
+ }
81
+ return null;
82
+ }
83
+ }
84
+
85
+ private boolean shouldSubscribeNatively(SubscriptionDefinition definition) {
86
+ return shouldInvokeNativeLogic(definition);
87
+ }
88
+
89
+ private boolean shouldUnsubscribeNatively(SubscriptionDefinition definition) {
90
+ return shouldInvokeNativeLogic(definition);
91
+ }
92
+
93
+ private boolean shouldInvokeNativeLogic(SubscriptionDefinition definition) {
94
+ if (definition.subscriptionType == SubscriptionType.MULTIPLE) {
95
+ return true;
96
+ }
97
+
98
+ return definition.subscriptionType == SubscriptionType.SINGLE && !subscriptionsExists(definition.eventType);
99
+ }
100
+
101
+ private boolean subscriptionsExists(String eventType) {
102
+ synchronized (mSubscriptions) {
103
+ for (Subscription sub : mSubscriptions) {
104
+ if (sub.eventType.equals(eventType)) {
105
+ return true;
106
+ }
107
+ }
108
+ return false;
109
+ }
110
+ }
111
+
112
+ private static class Subscription<T> {
113
+ private final int id;
114
+ @Nullable
115
+ private final T eventEmitterLogic;
116
+ private final String eventType;
117
+
118
+ public Subscription(int id, @Nullable T eventEmmitterLogic, String eventType) {
119
+ this.id = id;
120
+ this.eventEmitterLogic = eventEmmitterLogic;
121
+ this.eventType = eventType;
122
+ }
123
+
124
+ @Override
125
+ public boolean equals(Object o) {
126
+ if (this == o) return true;
127
+ if (o == null || getClass() != o.getClass()) return false;
128
+ Subscription<?> that = (Subscription<?>) o;
129
+ return id == that.id && Objects.equals(eventEmitterLogic, that.eventEmitterLogic) && Objects.equals(eventType, that.eventType);
130
+ }
131
+
132
+ @Override
133
+ public int hashCode() {
134
+ return Objects.hash(id, eventEmitterLogic, eventType);
135
+ }
136
+
137
+ @Override
138
+ public String toString() {
139
+ return "Subscription{" +
140
+ "id=" + id +
141
+ ", eventType='" + eventType + '\'' +
142
+ '}';
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Outlines how the native code should react to incoming requests in order to subscribe to/unsubscribe from
148
+ * global events from the JS code.
149
+ * <br/>
150
+ * <p>
151
+ * It defines how to add a listener on the Sentiance SDK to get updates related to the provided <code>eventType</code>,
152
+ * and how to remove the said listener.
153
+ * </p>
154
+ *
155
+ * @param <T> The type of the Sentiance SDK listener to be added/removed.
156
+ */
157
+ private static class SubscriptionDefinition<T> {
158
+ private final String eventType;
159
+ /**
160
+ * The subscription logic to run towards the native SDK.
161
+ */
162
+ private final SingleParamRunnable<T> nativeSubscribeLogic;
163
+ /**
164
+ * The unsubscription logic to run towards the native SDK.
165
+ */
166
+ private final SingleParamRunnable<T> nativeUnsubscribeLogic;
167
+
168
+ private final SubscriptionType subscriptionType;
169
+
170
+ public SubscriptionDefinition(String eventType, SingleParamRunnable<T> nativeSubscribeLogic,
171
+ SingleParamRunnable<T> nativeUnsubscribeLogic, SubscriptionType subscriptionType) {
172
+ this.eventType = eventType;
173
+ this.nativeSubscribeLogic = nativeSubscribeLogic;
174
+ this.nativeUnsubscribeLogic = nativeUnsubscribeLogic;
175
+ this.subscriptionType = subscriptionType;
176
+ }
177
+
178
+ @Override
179
+ public String toString() {
180
+ return "SubscriptionDefinition{" +
181
+ "eventType='" + eventType + '\'' +
182
+ ", subscriptionType=" + subscriptionType +
183
+ '}';
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Indicates whether the Sentiance SDK supports setting multiple listeners for a certain event type,
189
+ * or just a single listener.
190
+ *
191
+ * <pre>
192
+ * {@code
193
+ * someSentianceApi.setSomeEventListener(); // SINGLE
194
+ * someSentianceApi.addSomeEventListener(); // MULTIPLE
195
+ * }
196
+ * </pre>
197
+ */
198
+ public enum SubscriptionType {
199
+ SINGLE,
200
+ MULTIPLE
201
+ }
202
+ }
@@ -0,0 +1,6 @@
1
+ package com.sentiance.react.bridge.core.utils;
2
+
3
+ @FunctionalInterface
4
+ public interface SingleParamRunnable<T> {
5
+ void run(T t);
6
+ }
@@ -49,5 +49,7 @@ typedef NS_ENUM(NSInteger, UIBackgroundRefreshStatus);
49
49
  - (NSString*)convertBackgroundRefreshStatus:(UIBackgroundRefreshStatus)backgroundRefreshStatus;
50
50
  - (NSSet<NSString*> *)convertIntegerTransmittableDataTypes:(NSArray<NSNumber*>*)intDataTypes;
51
51
  - (NSSet<NSNumber*> *)convertStringTransmittableDataTypes:(NSArray<NSString*>*)stringDataTypes;
52
+ - (NSDictionary *)convertDrivingInsights:(SENTDrivingInsights *)drivingInsights;
53
+ - (NSArray *)convertHarshDrivingEvents:(NSArray<SENTHarshDrivingEvent*> *)harshDrivingEvents;
52
54
 
53
55
  @end
@@ -241,17 +241,8 @@
241
241
 
242
242
  - (NSMutableDictionary*)convertEvent:(SENTTimelineEvent*)event {
243
243
  NSMutableDictionary *eventDict = [[NSMutableDictionary alloc] init];
244
- eventDict[@"startTime"] = [event.startDate description];
245
- eventDict[@"startTimeEpoch"] = @((long) (event.startDate.timeIntervalSince1970 * 1000));
246
- if (event.endDate != nil) {
247
- eventDict[@"endTime"] = [event.endDate description];
248
- eventDict[@"endTimeEpoch"] = @((long) (event.endDate.timeIntervalSince1970 * 1000));
249
244
 
250
- NSInteger durationInSeconds = event.durationInSeconds;
251
- if (durationInSeconds != SENTDurationUnknown) {
252
- eventDict[@"durationInSeconds"] = [NSNumber numberWithInt:(int)durationInSeconds];
253
- }
254
- }
245
+ [self _addBaseEventFields:eventDict event:event];
255
246
 
256
247
  eventDict[@"type"] = [self convertTimelineEventTypeToString:event.type];
257
248
 
@@ -265,6 +256,22 @@
265
256
  return eventDict;
266
257
  }
267
258
 
259
+ - (NSMutableDictionary*) _addBaseEventFields:(NSMutableDictionary*) eventDict event: (SENTTimelineEvent*)event {
260
+ eventDict[@"id"] = [event eventId];
261
+ eventDict[@"startTime"] = [event.startDate description];
262
+ eventDict[@"startTimeEpoch"] = @((long) (event.startDate.timeIntervalSince1970 * 1000));
263
+ if (event.endDate != nil) {
264
+ eventDict[@"endTime"] = [event.endDate description];
265
+ eventDict[@"endTimeEpoch"] = @((long) (event.endDate.timeIntervalSince1970 * 1000));
266
+
267
+ NSInteger durationInSeconds = event.durationInSeconds;
268
+ if (durationInSeconds != SENTDurationUnknown) {
269
+ eventDict[@"durationInSeconds"] = [NSNumber numberWithInt:(int)durationInSeconds];
270
+ }
271
+ }
272
+ return eventDict;
273
+ }
274
+
268
275
  - (nullable NSString*)convertSegmentCategoryToString:(SENTSegmentCategory)category {
269
276
  switch (category) {
270
277
  case SENTSegmentCategoryLeisure:
@@ -317,40 +324,18 @@
317
324
  return @"ANTICIPATIVE_DRIVER";
318
325
  case SENTSegmentTypeBarGoer:
319
326
  return @"BAR_GOER";
320
- case SENTSegmentTypeBeautyQueen:
321
- return @"BEAUTY_QUEEN";
322
- case SENTSegmentTypeBrandLoyalBar:
323
- return @"BRAND_LOYAL__BAR";
324
- case SENTSegmentTypeBrandLoyalCafe:
325
- return @"BRAND_LOYAL__CAFE";
326
- case SENTSegmentTypeBrandLoyalRestaurant:
327
- return @"BRAND_LOYAL__RESTAURANT";
328
- case SENTSegmentTypeBrandLoyalRetail:
329
- return @"BRAND_LOYAL__RETAIL";
330
- case SENTSegmentTypeBrandLoyalty:
331
- return @"BRAND_LOYALTY";
332
- case SENTSegmentTypeBrandLoyaltyGasStations:
333
- return @"BRAND_LOYALTY__GAS_STATIONS";
334
- case SENTSegmentTypeBrandLoyaltyRestaurantBar:
335
- return @"BRAND_LOYALTY__RESTAURANT_BAR";
336
- case SENTSegmentTypeBrandLoyaltySupermarket:
337
- return @"BRAND_LOYALTY__SUPERMARKET";
338
327
  case SENTSegmentTypeCityDriver:
339
328
  return @"CITY_DRIVER";
340
329
  case SENTSegmentTypeCityHome:
341
330
  return @"CITY_HOME";
342
331
  case SENTSegmentTypeCityWorker:
343
332
  return @"CITY_WORKER";
344
- case SENTSegmentTypeClubber:
345
- return @"CLUBBER";
346
333
  case SENTSegmentTypeCultureBuff:
347
334
  return @"CULTURE_BUFF";
348
335
  case SENTSegmentTypeDieHardDriver:
349
336
  return @"DIE_HARD_DRIVER";
350
337
  case SENTSegmentTypeDistractedDriver:
351
338
  return @"DISTRACTED_DRIVER";
352
- case SENTSegmentTypeDoItYourselver:
353
- return @"DO_IT_YOURSELVER";
354
339
  case SENTSegmentTypeDogWalker:
355
340
  return @"DOG_WALKER";
356
341
  case SENTSegmentTypeEarlyBird:
@@ -359,16 +344,12 @@
359
344
  return @"EASY_COMMUTER";
360
345
  case SENTSegmentTypeEfficientDriver:
361
346
  return @"EFFICIENT_DRIVER";
362
- case SENTSegmentTypeFashionista:
363
- return @"FASHIONISTA";
364
347
  case SENTSegmentTypeFoodie:
365
348
  return @"FOODIE";
366
349
  case SENTSegmentTypeFrequentFlyer:
367
350
  return @"FREQUENT_FLYER";
368
351
  case SENTSegmentTypeFulltimeWorker:
369
352
  return @"FULLTIME_WORKER";
370
- case SENTSegmentTypeGamer:
371
- return @"GAMER";
372
353
  case SENTSegmentTypeGreenCommuter:
373
354
  return @"GREEN_COMMUTER";
374
355
  case SENTSegmentTypeHealthyBiker:
@@ -431,34 +412,6 @@
431
412
  return @"RECENTLY_MOVED_HOME";
432
413
  case SENTSegmentTypeRestoLover:
433
414
  return @"RESTO_LOVER";
434
- case SENTSegmentTypeRestoLoverAmerican:
435
- return @"RESTO_LOVER__AMERICAN";
436
- case SENTSegmentTypeRestoLoverAsian:
437
- return @"RESTO_LOVER__ASIAN";
438
- case SENTSegmentTypeRestoLoverBarbecue:
439
- return @"RESTO_LOVER__BARBECUE";
440
- case SENTSegmentTypeRestoLoverFastfood:
441
- return @"RESTO_LOVER__FASTFOOD";
442
- case SENTSegmentTypeRestoLoverFrench:
443
- return @"RESTO_LOVER__FRENCH";
444
- case SENTSegmentTypeRestoLoverGerman:
445
- return @"RESTO_LOVER__GERMAN";
446
- case SENTSegmentTypeRestoLoverGreek:
447
- return @"RESTO_LOVER__GREEK";
448
- case SENTSegmentTypeRestoLoverGrill:
449
- return @"RESTO_LOVER__GRILL";
450
- case SENTSegmentTypeRestoLoverInternational:
451
- return @"RESTO_LOVER__INTERNATIONAL";
452
- case SENTSegmentTypeRestoLoverItalian:
453
- return @"RESTO_LOVER__ITALIAN";
454
- case SENTSegmentTypeRestoLoverMediterranean:
455
- return @"RESTO_LOVER__MEDITERRANEAN";
456
- case SENTSegmentTypeRestoLoverMexican:
457
- return @"RESTO_LOVER__MEXICAN";
458
- case SENTSegmentTypeRestoLoverSeafood:
459
- return @"RESTO_LOVER__SEAFOOD";
460
- case SENTSegmentTypeRestoLoverSnack:
461
- return @"RESTO_LOVER__SNACK";
462
415
  case SENTSegmentTypeRuralHome:
463
416
  return @"RURAL_HOME";
464
417
  case SENTSegmentTypeRuralWorker:
@@ -1168,4 +1121,35 @@
1168
1121
  return [typesSet copy];
1169
1122
  }
1170
1123
 
1124
+ - (NSDictionary<NSString *, NSDictionary<NSString *, NSNumber *> *> *)convertDrivingInsights:(SENTDrivingInsights *)drivingInsights {
1125
+ NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
1126
+ NSMutableDictionary *transportEventDict = [[NSMutableDictionary alloc] init];
1127
+ NSMutableDictionary *safetyScoresDict = [[NSMutableDictionary alloc] init];
1128
+
1129
+ [self _addBaseEventFields:transportEventDict event:drivingInsights.transportEvent];
1130
+ [self addTransportEventInfoToDict:transportEventDict event:drivingInsights.transportEvent];
1131
+ dict[@"transportEvent"] = transportEventDict;
1132
+
1133
+ safetyScoresDict[@"smoothScore"] = drivingInsights.safetyScores.smoothScore;
1134
+ dict[@"safetyScores"] = safetyScoresDict;
1135
+
1136
+ return dict;
1137
+ }
1138
+
1139
+ - (NSArray<NSDictionary<NSString *, NSNumber *> *> *)convertHarshDrivingEvents:(NSArray<SENTHarshDrivingEvent*> *)harshDrivingEvents {
1140
+ NSMutableArray <NSDictionary<NSString *, NSNumber *> *> *array = [[NSMutableArray alloc] init];
1141
+ for (SENTHarshDrivingEvent *event in harshDrivingEvents) {
1142
+ [array addObject:[self convertHarshDrivingEvent:event]];
1143
+ }
1144
+ return array;
1145
+ }
1146
+
1147
+ - (NSDictionary<NSString *, NSNumber *> *)convertHarshDrivingEvent:(SENTHarshDrivingEvent *)harshDrivingEvent {
1148
+ NSMutableDictionary<NSString *, NSNumber *> *dict = [[NSMutableDictionary alloc] init];
1149
+ dict[@"time"] = [harshDrivingEvent.date description];
1150
+ dict[@"timeEpoch"] = @((long) (harshDrivingEvent.date.timeIntervalSince1970 * 1000));
1151
+ dict[@"magnitude"] = @(harshDrivingEvent.magnitude);
1152
+ return dict;
1153
+ }
1154
+
1171
1155
  @end
@@ -11,8 +11,9 @@ static NSString * _Nonnull const TripTimeoutEvent = @"SENTIANCE_ON_TRIP_TIMED_OU
11
11
  static NSString * _Nonnull const VehicleCrashEvent = @"SENTIANCE_VEHICLE_CRASH_EVENT";
12
12
  static NSString * _Nonnull const VehicleCrashDiagnosticEvent = @"SENTIANCE_VEHICLE_CRASH_DIAGNOSTIC_EVENT";
13
13
  static NSString * _Nonnull const UserContextUpdateEvent = @"SENTIANCE_USER_CONTEXT_UPDATE_EVENT";
14
+ static NSString * _Nonnull const DrivingInsightsReadyEvent = @"SENTIANCE_DRIVING_INSIGHTS_READY_EVENT";
14
15
 
15
- @interface RNSentianceCore : RCTEventEmitter <RCTBridgeModule, SENTUserContextDelegate>
16
+ @interface RNSentianceCore : RCTEventEmitter <RCTBridgeModule, SENTUserContextDelegate, SENTDrivingInsightsReadyDelegate>
16
17
  typedef void (^SdkStatusHandler)(SENTSDKStatus * _Nonnull status);
17
18
  - (SENTUserLinker _Nonnull ) getUserLinker;
18
19
  - (SdkStatusHandler _Nonnull) getSdkStatusUpdateHandler;
@@ -5,6 +5,7 @@
5
5
  #import "RNSentianceNativeInitialization.h"
6
6
  #import "RNSentianceCore+Converter.h"
7
7
  #import "RNSentianceErrorCodes.h"
8
+ #import "RNSentianceSubscriptionsManager.h"
8
9
 
9
10
  #define REJECT_IF_SDK_NOT_INITIALIZED(reject) if ([self isSdkNotInitialized]) { \
10
11
  reject(ESDKNotInitialized, @"Sdk not initialized", nil); \
@@ -15,6 +16,7 @@
15
16
 
16
17
  @property (nonatomic, strong) void (^userLinkSuccess)(void);
17
18
  @property (nonatomic, strong) void (^userLinkFailed)(void);
19
+ @property (nonatomic, strong) RNSentianceSubscriptionsManager* subscriptionsManager;
18
20
  @property (nonatomic, strong) SENTUserLinker userLinker;
19
21
  @property (nonatomic, strong) SdkStatusHandler sdkStatusHandler;
20
22
  @property (assign) BOOL userLinkingEnabled;
@@ -33,7 +35,7 @@ RCT_EXPORT_MODULE(SentianceCore)
33
35
 
34
36
  - (NSArray<NSString *> *)supportedEvents
35
37
  {
36
- return @[SdkStatusUpdateEvent, TripTimeoutEvent, UserLinkEvent, UserActivityUpdateEvent, VehicleCrashEvent, VehicleCrashDiagnosticEvent, UserLinkEvent, UserContextUpdateEvent];
38
+ return @[SdkStatusUpdateEvent, TripTimeoutEvent, UserLinkEvent, UserActivityUpdateEvent, VehicleCrashEvent, VehicleCrashDiagnosticEvent, UserLinkEvent, UserContextUpdateEvent, DrivingInsightsReadyEvent];
37
39
  }
38
40
 
39
41
  // Will be called when this module's first listener is added.
@@ -48,6 +50,29 @@ RCT_EXPORT_MODULE(SentianceCore)
48
50
  // Remove upstream listeners, stop unnecessary background tasks
49
51
  }
50
52
 
53
+ + (BOOL)requiresMainQueueSetup {
54
+ return NO;
55
+ }
56
+
57
+ - (void)onDrivingInsightsReadyWithInsights:(SENTDrivingInsights *)insights {
58
+ [self sendEventWithName:DrivingInsightsReadyEvent body:[self convertDrivingInsights:insights]];
59
+ }
60
+
61
+ - (instancetype)init
62
+ {
63
+ self = [super init];
64
+ _subscriptionsManager = [RNSentianceSubscriptionsManager new];
65
+ __weak typeof(self) weakSelf = self;
66
+
67
+ [_subscriptionsManager addSupportedSubscriptionForEventType:DrivingInsightsReadyEvent nativeSubscribeLogic:^{
68
+ [[Sentiance sharedInstance] setDrivingInsightsReadyDelegate:weakSelf];
69
+ } nativeUnsubscribeLogic:^{
70
+ [[Sentiance sharedInstance] setDrivingInsightsReadyDelegate:nil];
71
+ } subscriptionType:SENTSubscriptionTypeSingle];
72
+
73
+ return self;
74
+ }
75
+
51
76
  - (void) initSDK:(NSString *)appId
52
77
  secret:(NSString *)secret
53
78
  baseURL:(nullable NSString *)baseURL
@@ -993,7 +1018,7 @@ RCT_EXPORT_METHOD(listenTripTimeout:(RCTPromiseResolveBlock)resolve rejecter:(RC
993
1018
  RCT_EXPORT_METHOD(setTransmittableDataTypes:(NSArray *)types resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
994
1019
  {
995
1020
  REJECT_IF_SDK_NOT_INITIALIZED(reject);
996
-
1021
+
997
1022
  NSSet *typesSet = [NSSet setWithArray:types];
998
1023
  NSSet *convertedTypes = [self convertStringTransmittableDataTypes:types];
999
1024
  [[Sentiance sharedInstance] setTransmittableDataTypes:convertedTypes];
@@ -1002,13 +1027,49 @@ RCT_EXPORT_METHOD(setTransmittableDataTypes:(NSArray *)types resolver:(RCTPromis
1002
1027
  RCT_EXPORT_METHOD(getTransmittableDataTypes:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
1003
1028
  {
1004
1029
  REJECT_IF_SDK_NOT_INITIALIZED(reject);
1005
-
1030
+
1006
1031
  NSSet *types = [[Sentiance sharedInstance] transmittableDataTypes];
1007
1032
  NSSet *convertedTypes = [self convertIntegerTransmittableDataTypes:types];
1008
1033
  NSArray *array = [convertedTypes allObjects];
1009
1034
  resolve(array);
1010
1035
  }
1011
1036
 
1037
+ RCT_EXPORT_METHOD(getDrivingInsights:(NSString*)transportId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
1038
+ {
1039
+ REJECT_IF_SDK_NOT_INITIALIZED(reject);
1040
+
1041
+ SENTDrivingInsights *drivingInsights = [[Sentiance sharedInstance] getDrivingInsightsForTransportId:transportId];
1042
+ if (drivingInsights == nil) {
1043
+ resolve(nil);
1044
+ return;
1045
+ }
1046
+ resolve([self convertDrivingInsights:drivingInsights]);
1047
+ }
1048
+
1049
+ RCT_EXPORT_METHOD(getHarshDrivingEvents:(NSString*)transportId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
1050
+ {
1051
+ REJECT_IF_SDK_NOT_INITIALIZED(reject);
1052
+
1053
+ NSArray<SENTHarshDrivingEvent *> *harshDrivingEvents = [[Sentiance sharedInstance] getHarshDrivingEventsForTransportId:transportId];
1054
+ resolve([self convertHarshDrivingEvents:harshDrivingEvents]);
1055
+ }
1056
+
1057
+ RCT_EXPORT_METHOD(addNativeListener:(NSString *)eventName subscriptionId:(NSInteger)subscriptionId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
1058
+ REJECT_IF_SDK_NOT_INITIALIZED(reject);
1059
+
1060
+ [_subscriptionsManager addSubscriptionForEventType:eventName subscriptionId:subscriptionId];
1061
+
1062
+ resolve(nil);
1063
+ }
1064
+
1065
+ RCT_EXPORT_METHOD(removeNativeListener:(NSString *)eventName subscriptionId:(NSInteger)subscriptionId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
1066
+ REJECT_IF_SDK_NOT_INITIALIZED(reject);
1067
+
1068
+ [_subscriptionsManager removeSubscriptionForId:subscriptionId eventType:eventName];
1069
+
1070
+ resolve(nil);
1071
+ }
1072
+
1012
1073
  - (void)didUpdateUserContext:(SENTUserContext *)userContext
1013
1074
  forCriteriaMask:(SENTUserContextUpdateCriteria)criteriaMask {
1014
1075
  NSDictionary *dict = @{
@@ -4,7 +4,7 @@ sentiance_sdk_version = package['sdkVersions']['ios']['sentiance']
4
4
 
5
5
  Pod::Spec.new do |s|
6
6
  s.name = "RNSentianceCore"
7
- s.version = "6.3.0-rc.1"
7
+ s.version = "6.3.0"
8
8
  s.summary = "RNSentianceCore"
9
9
  s.description = <<-DESC
10
10
  RNSentianceCore
@@ -12,6 +12,9 @@
12
12
  03AE2706282A80FE0085E48F /* RNSentianceCore.m in Sources */ = {isa = PBXBuildFile; fileRef = 03AE2701282A80FD0085E48F /* RNSentianceCore.m */; };
13
13
  03AE2707282A80FE0085E48F /* RNSentianceCore+Converter.m in Sources */ = {isa = PBXBuildFile; fileRef = 03AE2704282A80FD0085E48F /* RNSentianceCore+Converter.m */; };
14
14
  9AE9AE342527BDFA0070A307 /* RNSentianceNativeInitialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 9AE9AE332527BDFA0070A307 /* RNSentianceNativeInitialization.m */; };
15
+ DE07003329DC44B900C4FA5B /* RNSentianceSubscriptionDefinition.m in Sources */ = {isa = PBXBuildFile; fileRef = DE07002D29DC44B900C4FA5B /* RNSentianceSubscriptionDefinition.m */; };
16
+ DE07003429DC44B900C4FA5B /* RNSentianceSubscription.m in Sources */ = {isa = PBXBuildFile; fileRef = DE07002F29DC44B900C4FA5B /* RNSentianceSubscription.m */; };
17
+ DE07003529DC44B900C4FA5B /* RNSentianceSubscriptionsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DE07003029DC44B900C4FA5B /* RNSentianceSubscriptionsManager.m */; };
15
18
  /* End PBXBuildFile section */
16
19
 
17
20
  /* Begin PBXCopyFilesBuildPhase section */
@@ -36,8 +39,15 @@
36
39
  03AE2703282A80FD0085E48F /* RNSentianceCore+Converter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RNSentianceCore+Converter.h"; sourceTree = "<group>"; };
37
40
  03AE2704282A80FD0085E48F /* RNSentianceCore+Converter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RNSentianceCore+Converter.m"; sourceTree = "<group>"; };
38
41
  134814201AA4EA6300B7C361 /* libRNSentianceCore.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNSentianceCore.a; sourceTree = BUILT_PRODUCTS_DIR; };
42
+ 4C0B444329DD81A60094360E /* RNSentianceFoundation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNSentianceFoundation.h; sourceTree = "<group>"; };
39
43
  9AE9AE322527BDD90070A307 /* RNSentianceNativeInitialization.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNSentianceNativeInitialization.h; sourceTree = "<group>"; };
40
44
  9AE9AE332527BDFA0070A307 /* RNSentianceNativeInitialization.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNSentianceNativeInitialization.m; sourceTree = "<group>"; };
45
+ DE07002D29DC44B900C4FA5B /* RNSentianceSubscriptionDefinition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSentianceSubscriptionDefinition.m; sourceTree = "<group>"; };
46
+ DE07002E29DC44B900C4FA5B /* RNSentianceSubscription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSentianceSubscription.h; sourceTree = "<group>"; };
47
+ DE07002F29DC44B900C4FA5B /* RNSentianceSubscription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSentianceSubscription.m; sourceTree = "<group>"; };
48
+ DE07003029DC44B900C4FA5B /* RNSentianceSubscriptionsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSentianceSubscriptionsManager.m; sourceTree = "<group>"; };
49
+ DE07003129DC44B900C4FA5B /* RNSentianceSubscriptionsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSentianceSubscriptionsManager.h; sourceTree = "<group>"; };
50
+ DE07003229DC44B900C4FA5B /* RNSentianceSubscriptionDefinition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSentianceSubscriptionDefinition.h; sourceTree = "<group>"; };
41
51
  /* End PBXFileReference section */
42
52
 
43
53
  /* Begin PBXFrameworksBuildPhase section */
@@ -62,6 +72,7 @@
62
72
  58B511D21A9E6C8500147676 = {
63
73
  isa = PBXGroup;
64
74
  children = (
75
+ 4C0B444329DD81A60094360E /* RNSentianceFoundation.h */,
65
76
  03AE2702282A80FD0085E48F /* RNSentianceErrorCodes.h */,
66
77
  03AE26FF282A80FD0085E48F /* RNSentianceErrorCodes.m */,
67
78
  03AE2700282A80FD0085E48F /* RNSentianceCore.h */,
@@ -70,8 +81,14 @@
70
81
  03AE2704282A80FD0085E48F /* RNSentianceCore+Converter.m */,
71
82
  03AE26FD282A80E90085E48F /* RNSentianceHelper.h */,
72
83
  03AE26FC282A80E90085E48F /* RNSentianceHelper.m */,
73
- 9AE9AE332527BDFA0070A307 /* RNSentianceNativeInitialization.m */,
84
+ DE07002E29DC44B900C4FA5B /* RNSentianceSubscription.h */,
85
+ DE07002F29DC44B900C4FA5B /* RNSentianceSubscription.m */,
86
+ DE07003229DC44B900C4FA5B /* RNSentianceSubscriptionDefinition.h */,
87
+ DE07002D29DC44B900C4FA5B /* RNSentianceSubscriptionDefinition.m */,
88
+ DE07003129DC44B900C4FA5B /* RNSentianceSubscriptionsManager.h */,
89
+ DE07003029DC44B900C4FA5B /* RNSentianceSubscriptionsManager.m */,
74
90
  9AE9AE322527BDD90070A307 /* RNSentianceNativeInitialization.h */,
91
+ 9AE9AE332527BDFA0070A307 /* RNSentianceNativeInitialization.m */,
75
92
  134814211AA4EA7D00B7C361 /* Products */,
76
93
  );
77
94
  sourceTree = "<group>";
@@ -135,7 +152,10 @@
135
152
  files = (
136
153
  03AE2707282A80FE0085E48F /* RNSentianceCore+Converter.m in Sources */,
137
154
  03AE26FE282A80E90085E48F /* RNSentianceHelper.m in Sources */,
155
+ DE07003329DC44B900C4FA5B /* RNSentianceSubscriptionDefinition.m in Sources */,
156
+ DE07003529DC44B900C4FA5B /* RNSentianceSubscriptionsManager.m in Sources */,
138
157
  03AE2706282A80FE0085E48F /* RNSentianceCore.m in Sources */,
158
+ DE07003429DC44B900C4FA5B /* RNSentianceSubscription.m in Sources */,
139
159
  9AE9AE342527BDFA0070A307 /* RNSentianceNativeInitialization.m in Sources */,
140
160
  03AE2705282A80FE0085E48F /* RNSentianceErrorCodes.m in Sources */,
141
161
  );
@@ -0,0 +1,11 @@
1
+ //
2
+ // RNSentianceFoundation.h
3
+ // RNSentianceCore
4
+ //
5
+ // Created by David Chelidze on 05/04/2023.
6
+ // Copyright © 2023 Facebook. All rights reserved.
7
+ //
8
+
9
+ #import <Foundation/Foundation.h>
10
+
11
+ typedef void (^SentianceBlock)(void);
@@ -0,0 +1,19 @@
1
+ //
2
+ // Subscription.h
3
+ // Pods
4
+ //
5
+ // Created by Mohammed Aouf Zouag on 27/3/2023.
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+
10
+
11
+ @interface RNSentianceSubscription : NSObject
12
+
13
+ @property (nonatomic, readonly) NSInteger subscriptionId;
14
+ @property (nonatomic, strong, readonly) NSString *eventType;
15
+
16
+ - (instancetype)init NS_UNAVAILABLE;
17
+ - (instancetype)initWithEventType:(NSString*)eventType subscriptionId:(NSInteger)subscriptionId NS_DESIGNATED_INITIALIZER;
18
+
19
+ @end
@@ -0,0 +1,30 @@
1
+ //
2
+ // Subscription.m
3
+ // DoubleConversion
4
+ //
5
+ // Created by Mohammed Aouf Zouag on 27/3/2023.
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+ #import "RNSentianceSubscription.h"
10
+
11
+
12
+ @interface RNSentianceSubscription ()
13
+
14
+ @property (nonatomic, readwrite) NSInteger subscriptionId;
15
+ @property (nonatomic, strong, readwrite) NSString *eventType;
16
+
17
+ @end
18
+
19
+ @implementation RNSentianceSubscription
20
+
21
+ - (instancetype)initWithEventType:(NSString *)eventType subscriptionId:(NSInteger)subscriptionId {
22
+ self = [super init];
23
+ if (self) {
24
+ self.eventType = eventType;
25
+ self.subscriptionId = subscriptionId;
26
+ }
27
+ return self;
28
+ }
29
+
30
+ @end
@@ -0,0 +1,32 @@
1
+ //
2
+ // RNSentianceSubscriptionMapping.h
3
+ // Pods
4
+ //
5
+ // Created by Mohammed Aouf Zouag on 27/3/2023.
6
+ //
7
+
8
+ #ifndef RNSentianceSubscriptionMapping_h
9
+ #define RNSentianceSubscriptionMapping_h
10
+
11
+ #import "RNSentianceFoundation.h"
12
+ typedef NS_ENUM(NSUInteger, SENTSubscriptionType) {
13
+ SENTSubscriptionTypeSingle,
14
+ SENTSubscriptionTypeMultiple,
15
+ };
16
+
17
+ @interface RNSentianceSubscriptionDefinition : NSObject
18
+
19
+ @property (nonatomic, strong, readonly) NSString *eventType;
20
+ @property (nonatomic, strong, readonly) SentianceBlock nativeSubscribeLogic;
21
+ @property (nonatomic, strong, readonly) SentianceBlock nativeUnsubscribeLogic;
22
+ @property (nonatomic, readonly) SENTSubscriptionType subscriptionType;
23
+
24
+ - (instancetype)init NS_UNAVAILABLE;
25
+ - (instancetype)initWithEventType:(NSString *)eventType
26
+ nativeSubscribeLogic:(SentianceBlock)nativeSubscribeLogic
27
+ nativeUnsubscribeLogic:(SentianceBlock)nativeUnsubscribeLogic
28
+ subscriptionType:(SENTSubscriptionType)subscriptionType NS_DESIGNATED_INITIALIZER;
29
+
30
+ @end
31
+
32
+ #endif /* RNSentianceSubscriptionMapping_h */
@@ -0,0 +1,36 @@
1
+ //
2
+ // RNSentianceSubscriptionMapping.m
3
+ // DoubleConversion
4
+ //
5
+ // Created by Mohammed Aouf Zouag on 27/3/2023.
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+ #import "RNSentianceSubscriptionDefinition.h"
10
+
11
+ @interface RNSentianceSubscriptionDefinition ()
12
+
13
+ @property (nonatomic, strong, readwrite) NSString *eventType;
14
+ @property (nonatomic, strong, readwrite) SentianceBlock nativeSubscribeLogic;
15
+ @property (nonatomic, strong, readwrite) SentianceBlock nativeUnsubscribeLogic;
16
+ @property (nonatomic, readwrite) SENTSubscriptionType subscriptionType;
17
+
18
+ @end
19
+
20
+ @implementation RNSentianceSubscriptionDefinition
21
+
22
+ - (instancetype)initWithEventType:(NSString *)eventType
23
+ nativeSubscribeLogic:(SentianceBlock)nativeSubscribeLogic
24
+ nativeUnsubscribeLogic:(SentianceBlock)nativeUnsubscribeLogic
25
+ subscriptionType:(SENTSubscriptionType)subscriptionType {
26
+ self = [super init];
27
+ if (self) {
28
+ self.eventType = eventType;
29
+ self.nativeSubscribeLogic = nativeSubscribeLogic;
30
+ self.nativeUnsubscribeLogic = nativeUnsubscribeLogic;
31
+ self.subscriptionType = subscriptionType;
32
+ }
33
+ return self;
34
+ }
35
+
36
+ @end
@@ -0,0 +1,26 @@
1
+ //
2
+ // SentianceSubscriptionsManager.h
3
+ // Pods
4
+ //
5
+ // Created by Mohammed Aouf Zouag on 27/3/2023.
6
+ //
7
+
8
+ #ifndef SentianceSubscriptionsManager_h
9
+ #define SentianceSubscriptionsManager_h
10
+
11
+ #import "RNSentianceFoundation.h"
12
+ #import "RNSentianceSubscriptionDefinition.h"
13
+ #import <SENTSDK/SENTSDK.h>
14
+
15
+ @interface RNSentianceSubscriptionsManager : NSObject
16
+
17
+ - (void)addSupportedSubscriptionForEventType:(NSString *)eventType
18
+ nativeSubscribeLogic:(SentianceBlock)nativeSubscribeLogic
19
+ nativeUnsubscribeLogic:(SentianceBlock)nativeUnsubscribeLogic
20
+ subscriptionType:(SENTSubscriptionType)subscriptionType;
21
+ - (void)addSubscriptionForEventType:(NSString *)eventType subscriptionId:(NSInteger)subscriptionId;
22
+ - (void)removeSubscriptionForId:(NSInteger)subscriptionId eventType:(NSString *)eventType;
23
+
24
+ @end
25
+
26
+ #endif /* SentianceSubscriptionsManager_h */
@@ -0,0 +1,117 @@
1
+ //
2
+ // SentianceSubscriptionsManager.m
3
+ // DoubleConversion
4
+ //
5
+ // Created by Mohammed Aouf Zouag on 27/3/2023.
6
+ //
7
+
8
+ #import <Foundation/Foundation.h>
9
+ #import "RNSentianceSubscriptionsManager.h"
10
+ #import "RNSentianceSubscriptionDefinition.h"
11
+ #import "RNSentianceSubscription.h"
12
+
13
+ @interface RNSentianceSubscriptionsManager()
14
+
15
+ @property (nonatomic, strong) NSMutableArray<RNSentianceSubscription*> *subscriptions;
16
+ @property (nonatomic, strong) NSMutableDictionary<NSString *, RNSentianceSubscriptionDefinition *> *supportedSubscriptions;
17
+
18
+ @end
19
+
20
+ @implementation RNSentianceSubscriptionsManager
21
+
22
+ - (instancetype)init {
23
+ self = [super init];
24
+ _subscriptions = [[NSMutableArray alloc] init];
25
+ _supportedSubscriptions = [[NSMutableDictionary alloc] init];
26
+ return self;
27
+ }
28
+
29
+ - (void)addSupportedSubscriptionForEventType:(NSString *)eventType
30
+ nativeSubscribeLogic:(SentianceBlock)nativeSubscribeLogic
31
+ nativeUnsubscribeLogic:(SentianceBlock)nativeUnsubscribeLogic
32
+ subscriptionType:(SENTSubscriptionType)subscriptionType {
33
+ @synchronized (_subscriptions) {
34
+ if (_supportedSubscriptions[eventType] == nil) {
35
+ RNSentianceSubscriptionDefinition *definition =
36
+ [[RNSentianceSubscriptionDefinition alloc]initWithEventType:eventType
37
+ nativeSubscribeLogic:nativeSubscribeLogic
38
+ nativeUnsubscribeLogic:nativeUnsubscribeLogic
39
+ subscriptionType:subscriptionType];
40
+ _supportedSubscriptions[eventType] = definition;
41
+ }
42
+ }
43
+ }
44
+
45
+ - (void)addSubscriptionForEventType:(NSString *)eventType subscriptionId:(NSInteger)subscriptionId {
46
+ RNSentianceSubscriptionDefinition *definition = _supportedSubscriptions[eventType];
47
+
48
+ if (definition != nil) {
49
+ if ([self _shouldSubscribeNatively:definition]) {
50
+ definition.nativeSubscribeLogic();
51
+ }
52
+
53
+ RNSentianceSubscription *subscription = [[RNSentianceSubscription alloc]initWithEventType:eventType
54
+ subscriptionId:subscriptionId];
55
+
56
+ @synchronized (_subscriptions) {
57
+ [_subscriptions addObject:subscription];
58
+ }
59
+ }
60
+ }
61
+
62
+ - (void)removeSubscriptionForId:(NSInteger)subscriptionId eventType:(NSString *)eventType {
63
+ RNSentianceSubscriptionDefinition *definition = _supportedSubscriptions[eventType];
64
+
65
+ if (definition != nil) {
66
+ RNSentianceSubscription *subscription = [self _getExistingSubscriptionWithId:subscriptionId eventType:eventType];
67
+ if (subscription != nil) {
68
+ @synchronized (_subscriptions) {
69
+ [_subscriptions removeObject:subscription];
70
+ }
71
+
72
+ if ([self _shouldUnsubscribeNatively:definition]) {
73
+ definition.nativeUnsubscribeLogic();
74
+ }
75
+ }
76
+ }
77
+ }
78
+
79
+ - (nullable RNSentianceSubscription *)_getExistingSubscriptionWithId:(NSInteger)subscriptionId eventType:(NSString *)eventType {
80
+ @synchronized (_subscriptions) {
81
+ for (RNSentianceSubscription *subscription in _subscriptions) {
82
+ if (subscription.subscriptionId == subscriptionId && [eventType isEqualToString:subscription.eventType]) {
83
+ return subscription;
84
+ }
85
+ }
86
+ return nil;
87
+ }
88
+ }
89
+
90
+ - (BOOL)_shouldSubscribeNatively:(RNSentianceSubscriptionDefinition*)definition {
91
+ return [self _shouldInvokeNativeLogic:definition];
92
+ }
93
+
94
+ - (BOOL)_shouldUnsubscribeNatively:(RNSentianceSubscriptionDefinition*)definition {
95
+ return [self _shouldInvokeNativeLogic:definition];
96
+ }
97
+
98
+ - (BOOL)_shouldInvokeNativeLogic:(RNSentianceSubscriptionDefinition*)definition {
99
+ if (definition.subscriptionType == SENTSubscriptionTypeMultiple) {
100
+ return true;
101
+ }
102
+
103
+ return definition.subscriptionType == SENTSubscriptionTypeSingle && [self _subscriptionExists:definition.eventType] == NO;
104
+ }
105
+
106
+ - (BOOL)_subscriptionExists:(NSString *)eventType {
107
+ @synchronized (_subscriptions) {
108
+ for (RNSentianceSubscription *subscription in _subscriptions) {
109
+ if ([subscription.eventType isEqualToString:eventType]) {
110
+ return YES;
111
+ }
112
+ }
113
+ return NO;
114
+ }
115
+ }
116
+
117
+ @end
@@ -0,0 +1,75 @@
1
+ import {EmitterSubscription, NativeEventEmitter, Platform} from "react-native";
2
+
3
+ class SentianceEventEmitter extends NativeEventEmitter {
4
+
5
+ constructor(nativeModule) {
6
+ super(nativeModule);
7
+
8
+ const bindings = this.requireNativeBindings(nativeModule);
9
+ this._addNativeListener = bindings.addNativeListener;
10
+ this._removeNativeListener = bindings.removeNativeListener;
11
+ }
12
+
13
+ requireNativeBindings(nativeModule) {
14
+ if (!nativeModule) {
15
+ throw new Error('Native module cannot have a null value.');
16
+ }
17
+ if (Platform.OS === 'android') {
18
+ return this.requireAndroidBindings(nativeModule);
19
+ } else {
20
+ return this.requireIosBindings(nativeModule);
21
+ }
22
+ }
23
+
24
+ requireAndroidBindings(nativeModule) {
25
+ const hasAddListener = typeof nativeModule.addListener === 'function';
26
+ const hasRemoveListener = typeof nativeModule.removeListener === 'function';
27
+
28
+ if (!hasAddListener) {
29
+ throw new Error('Native Android module does not expose an addListener function');
30
+ }
31
+ if (!hasRemoveListener) {
32
+ throw new Error('Native Android module does not expose a removeListener function');
33
+ }
34
+
35
+ return {
36
+ addNativeListener: nativeModule.addListener,
37
+ removeNativeListener: nativeModule.removeListener
38
+ };
39
+ }
40
+
41
+ requireIosBindings(nativeModule) {
42
+ const hasAddListener = typeof nativeModule.addNativeListener === 'function';
43
+ const hasRemoveListener = typeof nativeModule.removeNativeListener === 'function';
44
+
45
+ if (!hasAddListener) {
46
+ throw new Error('Native iOS module does not expose an addNativeListener function');
47
+ }
48
+ if (!hasRemoveListener) {
49
+ throw new Error('Native iOS module does not expose a removeNativeListener function');
50
+ }
51
+
52
+ return {
53
+ addNativeListener: nativeModule.addNativeListener,
54
+ removeNativeListener: nativeModule.removeNativeListener
55
+ };
56
+ }
57
+
58
+ async addListener(eventType, listener, context): EmitterSubscription {
59
+ const subscription = super.addListener(eventType, listener, context);
60
+ await this._addNativeListener(eventType, subscription.key);
61
+ return subscription;
62
+ }
63
+
64
+ async clearSubscription(eventType, subscription) {
65
+ if (super.removeSubscription != null) {
66
+ super.removeSubscription(subscription);
67
+ } else {
68
+ // RN 0.64+ no longer provides a removeSubscription function
69
+ subscription.remove();
70
+ }
71
+ await this._removeNativeListener(eventType, subscription.key);
72
+ }
73
+ }
74
+
75
+ module.exports = SentianceEventEmitter;
@@ -0,0 +1,12 @@
1
+ const SentianceEventEmitter = require("@sentiance-react-native/core/lib/SentianceEventEmitter");
2
+
3
+ exports.createEventListener = async (eventName: String, emitter: SentianceEventEmitter, callback: Function) => {
4
+ const listener = (data) => {
5
+ callback(data);
6
+ };
7
+ const subscription = await emitter.addListener(eventName, listener);
8
+ subscription.remove = async function () {
9
+ await emitter.clearSubscription(eventName, subscription);
10
+ }
11
+ return subscription;
12
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentiance-react-native/core",
3
- "version": "6.3.0-rc.1",
3
+ "version": "6.3.0",
4
4
  "description": "React Native Sentiance core library",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -29,10 +29,10 @@
29
29
  "targetSdk": 31,
30
30
  "compileSdk": 31,
31
31
  "buildTools": "30.0.3",
32
- "sentiance": "6.3.0-rc1"
32
+ "sentiance": "6.3.+"
33
33
  },
34
34
  "ios": {
35
- "sentiance": "~> 6.3.0-rc2"
35
+ "sentiance": "~> 6.3.0"
36
36
  }
37
37
  }
38
38
  }