@truewatchtech/react-native-mobile 0.3.15 → 0.4.1

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.
Files changed (113) hide show
  1. package/FTMobileReactNativeSDK.podspec +32 -2
  2. package/android/build.gradle +10 -4
  3. package/android/src/main/java/com/ft/sdk/reactnative/FTMobileImpl.java +434 -5
  4. package/android/src/main/java/com/ft/sdk/reactnative/FTRUMImpl.java +12 -0
  5. package/android/src/main/java/com/ft/sdk/reactnative/FTTraceImpl.java +1 -1
  6. package/android/src/newarch/java/com/ft/sdk/reactnative/FTLogModule.java +7 -14
  7. package/android/src/newarch/java/com/ft/sdk/reactnative/FTMobileModule.java +46 -12
  8. package/android/src/newarch/java/com/ft/sdk/reactnative/FTRUMModule.java +12 -13
  9. package/android/src/newarch/java/com/ft/sdk/reactnative/FTTraceModule.java +6 -8
  10. package/android/src/oldarch/java/com/ft/sdk/reactnative/FTMobileModule.java +34 -2
  11. package/android/src/rnpost74/java/com/ft/sdk/reactnative/FTMobilePackage.java +14 -4
  12. package/android/src/rnpre74/java/com/ft/sdk/reactnative/FTMobilePackage.java +0 -2
  13. package/ios/FTMobileReactNative.h +9 -5
  14. package/ios/FTMobileReactNative.mm +619 -0
  15. package/ios/FTReactNativeLog.h +8 -3
  16. package/ios/FTReactNativeLog.mm +79 -0
  17. package/ios/FTReactNativeRUM.h +8 -4
  18. package/ios/{FTReactNativeRUM.m → FTReactNativeRUM.mm} +143 -84
  19. package/ios/FTReactNativeTrace.h +7 -3
  20. package/ios/FTReactNativeTrace.mm +74 -0
  21. package/ios/FtMobileAgent.xcodeproj/project.pbxproj +22 -0
  22. package/lib/commonjs/ft_logger.js +14 -13
  23. package/lib/commonjs/ft_logger.js.map +1 -1
  24. package/lib/commonjs/ft_mobile_agent.js +153 -6
  25. package/lib/commonjs/ft_mobile_agent.js.map +1 -1
  26. package/lib/commonjs/ft_rum.js +55 -21
  27. package/lib/commonjs/ft_rum.js.map +1 -1
  28. package/lib/commonjs/ft_tracing.js +29 -10
  29. package/lib/commonjs/ft_tracing.js.map +1 -1
  30. package/lib/commonjs/index.js +30 -0
  31. package/lib/commonjs/index.js.map +1 -1
  32. package/lib/commonjs/rum/FTRumActionTracking.js +10 -4
  33. package/lib/commonjs/rum/FTRumActionTracking.js.map +1 -1
  34. package/lib/commonjs/rum/FTRumErrorTracking.js +4 -4
  35. package/lib/commonjs/rum/FTRumErrorTracking.js.map +1 -1
  36. package/lib/commonjs/specs/NativeFTMobileReactNative.js +10 -0
  37. package/lib/commonjs/specs/NativeFTMobileReactNative.js.map +1 -0
  38. package/lib/commonjs/specs/NativeFTReactNativeLog.js +10 -0
  39. package/lib/commonjs/specs/NativeFTReactNativeLog.js.map +1 -0
  40. package/lib/commonjs/specs/NativeFTReactNativeRUM.js +10 -0
  41. package/lib/commonjs/specs/NativeFTReactNativeRUM.js.map +1 -0
  42. package/lib/commonjs/specs/NativeFTReactNativeTrace.js +10 -0
  43. package/lib/commonjs/specs/NativeFTReactNativeTrace.js.map +1 -0
  44. package/lib/commonjs/version.js +1 -1
  45. package/lib/commonjs/version.js.map +1 -1
  46. package/lib/module/ft_logger.js +14 -12
  47. package/lib/module/ft_logger.js.map +1 -1
  48. package/lib/module/ft_mobile_agent.js +159 -5
  49. package/lib/module/ft_mobile_agent.js.map +1 -1
  50. package/lib/module/ft_rum.js +54 -16
  51. package/lib/module/ft_rum.js.map +1 -1
  52. package/lib/module/ft_tracing.js +29 -9
  53. package/lib/module/ft_tracing.js.map +1 -1
  54. package/lib/module/index.js +3 -3
  55. package/lib/module/index.js.map +1 -1
  56. package/lib/module/rum/FTRumActionTracking.js +10 -4
  57. package/lib/module/rum/FTRumActionTracking.js.map +1 -1
  58. package/lib/module/rum/FTRumErrorTracking.js +4 -4
  59. package/lib/module/rum/FTRumErrorTracking.js.map +1 -1
  60. package/lib/module/specs/NativeFTMobileReactNative.js +5 -0
  61. package/lib/module/specs/NativeFTMobileReactNative.js.map +1 -0
  62. package/lib/module/specs/NativeFTReactNativeLog.js +5 -0
  63. package/lib/module/specs/NativeFTReactNativeLog.js.map +1 -0
  64. package/lib/module/specs/NativeFTReactNativeRUM.js +5 -0
  65. package/lib/module/specs/NativeFTReactNativeRUM.js.map +1 -0
  66. package/lib/module/specs/NativeFTReactNativeTrace.js +5 -0
  67. package/lib/module/specs/NativeFTReactNativeTrace.js.map +1 -0
  68. package/lib/module/version.js +1 -1
  69. package/lib/module/version.js.map +1 -1
  70. package/lib/typescript/ft_logger.d.ts +6 -6
  71. package/lib/typescript/ft_mobile_agent.d.ts +165 -14
  72. package/lib/typescript/ft_rum.d.ts +32 -8
  73. package/lib/typescript/ft_tracing.d.ts +6 -6
  74. package/lib/typescript/index.d.ts +3 -3
  75. package/lib/typescript/specs/NativeFTMobileReactNative.d.ts +75 -0
  76. package/lib/typescript/specs/NativeFTReactNativeLog.d.ts +23 -0
  77. package/lib/typescript/specs/NativeFTReactNativeRUM.d.ts +89 -0
  78. package/lib/typescript/specs/NativeFTReactNativeTrace.d.ts +24 -0
  79. package/lib/typescript/version.d.ts +1 -1
  80. package/package.json +29 -96
  81. package/scripts/replace-react-require.js +37 -38
  82. package/src/ft_logger.tsx +71 -40
  83. package/src/ft_mobile_agent.tsx +374 -92
  84. package/src/ft_rum.tsx +227 -123
  85. package/src/ft_tracing.tsx +58 -38
  86. package/src/index.tsx +58 -16
  87. package/src/rum/FTRumActionTracking.tsx +212 -204
  88. package/src/rum/FTRumErrorTracking.tsx +70 -71
  89. package/src/specs/NativeFTMobileReactNative.ts +83 -0
  90. package/src/specs/NativeFTReactNativeLog.ts +29 -0
  91. package/src/specs/NativeFTReactNativeRUM.ts +104 -0
  92. package/src/specs/NativeFTReactNativeTrace.ts +26 -0
  93. package/src/version.ts +1 -1
  94. package/LICENSE +0 -201
  95. package/android/.project +0 -17
  96. package/android/.settings/org.eclipse.buildship.core.prefs +0 -13
  97. package/android/gradlew +0 -185
  98. package/android/local.properties +0 -8
  99. package/android/src/main/java/com/ft/sdk/InnerClassProxy.java +0 -8
  100. package/ios/.idea/.name +0 -1
  101. package/ios/.idea/ios.iml +0 -2
  102. package/ios/.idea/modules.xml +0 -8
  103. package/ios/.idea/vcs.xml +0 -6
  104. package/ios/.idea/xcode.xml +0 -4
  105. package/ios/FTMobileReactNative.m +0 -183
  106. package/ios/FTReactNativeLog.m +0 -60
  107. package/ios/FTReactNativeTrace.m +0 -58
  108. package/ios/FtMobileAgent.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -4
  109. package/ios/FtMobileAgent.xcodeproj/project.xcworkspace/xcuserdata/Brandon.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  110. package/ios/FtMobileAgent.xcodeproj/project.xcworkspace/xcuserdata/Brandon.xcuserdatad/xcschemes/xcschememanagement.plist +0 -5
  111. package/ios/FtMobileAgent.xcodeproj/xcuserdata/Brandon.xcuserdatad/xcschemes/FtMobileAgent.xcscheme +0 -56
  112. package/ios/FtMobileAgent.xcodeproj/xcuserdata/Brandon.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  113. package/ios/RCTVersion.h +0 -8
@@ -0,0 +1,619 @@
1
+ //
2
+ // FTMobileReactNative.m
3
+ // FtMobileAgent
4
+ //
5
+ // Created by Hu Leilei on 2021/12/14.
6
+ // Copyright © 2021 Facebook. All rights reserved.
7
+ //
8
+
9
+ #import "FTMobileReactNative.h"
10
+ #import <React/RCTConvert.h>
11
+ #import <FTMobileSDK/FTMobileAgent.h>
12
+ #import <FTMobileSDK/FTMobileConfig+Private.h>
13
+ #import <FTMobileSDK/FTThreadDispatchManager.h>
14
+ #import <FTMobileSDK/FTConstants.h>
15
+ #import <FTMobileSDK/FTJSONUtil.h>
16
+ #import <FTMobileSDK/FTRemoteConfigModel+Private.h>
17
+
18
+ static NSString *const FTRemoteConfigCallbackEvent = @"ft_remote_config_callback";
19
+
20
+ @implementation FTMobileReactNative
21
+ {
22
+ BOOL _hasListeners;
23
+ BOOL _remoteConfigurationEnabled;
24
+ int _remoteConfigMiniUpdateInterval;
25
+ NSArray<NSDictionary *> *_remoteConfigOverrideRules;
26
+ }
27
+
28
+ RCT_EXPORT_MODULE()
29
+
30
+ - (NSArray<NSString *> *)supportedEvents
31
+ {
32
+ return @[FTRemoteConfigCallbackEvent];
33
+ }
34
+
35
+ - (void)startObserving
36
+ {
37
+ _hasListeners = YES;
38
+ }
39
+
40
+ - (void)stopObserving
41
+ {
42
+ _hasListeners = NO;
43
+ }
44
+
45
+ - (NSDictionary *)remoteConfigResultWithSuccess:(BOOL)success
46
+ content:(NSDictionary<NSString *, id> *_Nullable)content
47
+ error:(NSError *_Nullable)error
48
+ triggerType:(NSString *)triggerType
49
+ model:(FTRemoteConfigModel *_Nullable)model
50
+ rules:(NSArray<NSDictionary *> *_Nullable)rules
51
+ {
52
+ // Use local rules if provided, otherwise use global rules
53
+ NSArray<NSDictionary *> *rulesToApply = rules ?: _remoteConfigOverrideRules;
54
+ NSArray<NSString *> *appliedRuleIds = @[];
55
+
56
+ if (model && content && rulesToApply.count > 0) {
57
+ appliedRuleIds = [self applyRemoteConfigOverrideRulesWithModel:model content:content rules:rulesToApply];
58
+ }
59
+
60
+ NSMutableDictionary *payload = [NSMutableDictionary dictionary];
61
+ payload[@"triggerType"] = triggerType;
62
+ payload[@"success"] = @(success);
63
+ payload[@"platform"] = @"ios";
64
+ payload[@"timestamp"] = @((long long)([[NSDate date] timeIntervalSince1970] * 1000));
65
+
66
+ // Overridden content after applying rules
67
+ if (model && appliedRuleIds.count > 0) {
68
+ NSDictionary *overriddenContent = [model toDictionary];
69
+ payload[@"rawJson"] = [FTJSONUtil convertToJsonData:overriddenContent];
70
+ payload[@"appliedOverrideRuleIds"] = appliedRuleIds;
71
+ } else if (content) {
72
+ payload[@"rawJson"] = [FTJSONUtil convertToJsonData:content];
73
+ }
74
+ if (error) {
75
+ payload[@"errorCode"] = @(error.code);
76
+ payload[@"errorMessage"] = error.localizedDescription ?: @"";
77
+ }
78
+ return payload;
79
+ }
80
+
81
+ - (void)emitAutoRemoteConfigEventWithSuccess:(BOOL)success
82
+ content:(NSDictionary<NSString *, id> *_Nullable)content
83
+ error:(NSError *_Nullable)error
84
+ model:(FTRemoteConfigModel *_Nullable)model
85
+ {
86
+ if (!_hasListeners) {
87
+ return;
88
+ }
89
+ [self sendEventWithName:FTRemoteConfigCallbackEvent
90
+ body:[self remoteConfigResultWithSuccess:success
91
+ content:content
92
+ error:error
93
+ triggerType:@"auto"
94
+ model:model
95
+ rules:nil]];
96
+ }
97
+
98
+ - (BOOL)isEqualValue:(id)value1 toValue:(id)value2 {
99
+ if (value1 == nil && value2 == nil) {
100
+ return YES;
101
+ }
102
+ if (value1 == nil || value2 == nil) {
103
+ return NO;
104
+ }
105
+
106
+ if ([value1 isKindOfClass:[NSString class]]) {
107
+ id normalizedValue1 = [self parsedJSONArrayIfNeeded:value1];
108
+ if (normalizedValue1 != value1) {
109
+ return [self isEqualValue:normalizedValue1 toValue:value2];
110
+ }
111
+ }
112
+
113
+ // Handle NSNumber comparison
114
+ if ([value1 isKindOfClass:[NSNumber class]] && [value2 isKindOfClass:[NSNumber class]]) {
115
+ return [value1 isEqualToNumber:value2];
116
+ }
117
+
118
+ // Handle NSString comparison
119
+ if ([value1 isKindOfClass:[NSString class]] && [value2 isKindOfClass:[NSString class]]) {
120
+ return [value1 isEqualToString:value2];
121
+ }
122
+
123
+ // Handle NSArray comparison
124
+ if ([value1 isKindOfClass:[NSArray class]] && [value2 isKindOfClass:[NSArray class]]) {
125
+ return [value1 isEqualToArray:value2];
126
+ }
127
+
128
+ // Handle NSDictionary comparison
129
+ if ([value1 isKindOfClass:[NSDictionary class]] && [value2 isKindOfClass:[NSDictionary class]]) {
130
+ return [value1 isEqualToDictionary:value2];
131
+ }
132
+
133
+ // For other types, use description comparison as fallback
134
+ return [[value1 description] isEqualToString:[value2 description]];
135
+ }
136
+
137
+ - (BOOL)matchesCustomKeyActual:(id)actualValue expected:(id)expectedValue {
138
+ if ([expectedValue isKindOfClass:[NSDictionary class]]) {
139
+ NSDictionary *rule = (NSDictionary *)expectedValue;
140
+ id containsValue = rule[@"contains"];
141
+ if (containsValue != nil) {
142
+ return [self containsValueInActual:actualValue expected:containsValue];
143
+ }
144
+ }
145
+ return [self isEqualValue:actualValue toValue:expectedValue];
146
+ }
147
+
148
+ - (BOOL)containsValueInActual:(id)actualValue expected:(id)expectedValue {
149
+ id normalizedActual = [actualValue isKindOfClass:[NSString class]]
150
+ ? [self parsedJSONArrayIfNeeded:actualValue]
151
+ : actualValue;
152
+ if (![normalizedActual isKindOfClass:[NSArray class]]) {
153
+ return [self isEqualValue:normalizedActual toValue:expectedValue];
154
+ }
155
+ NSArray *array = (NSArray *)normalizedActual;
156
+ return [array containsObject:expectedValue];
157
+ }
158
+
159
+ - (id)parsedJSONArrayIfNeeded:(NSString *)value {
160
+ if (!value) return nil;
161
+
162
+ NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding];
163
+ NSError *error = nil;
164
+ id object = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
165
+
166
+ if (!error && [object isKindOfClass:[NSArray class]]) {
167
+ return object;
168
+ }
169
+ return value;
170
+ }
171
+
172
+ - (NSArray<NSString *> *)applyRemoteConfigOverrideRulesWithModel:(FTRemoteConfigModel *_Nullable)model
173
+ content:(NSDictionary<NSString *, id> *_Nullable)content
174
+ rules:(NSArray<NSDictionary *> *)rules
175
+ {
176
+ if (!model || !content || rules.count == 0) {
177
+ return @[];
178
+ }
179
+ NSMutableArray<NSString *> *appliedRuleIds = [NSMutableArray array];
180
+ [rules enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull rule, NSUInteger idx, BOOL * _Nonnull stop) {
181
+ BOOL enabled = ![rule.allKeys containsObject:@"enabled"] || [RCTConvert BOOL:rule[@"enabled"]];
182
+ if (!enabled) {
183
+ return;
184
+ }
185
+ NSDictionary *match = [RCTConvert NSDictionary:rule[@"match"]];
186
+ NSDictionary *customKeys = [RCTConvert NSDictionary:match[@"customKeys"]];
187
+ NSDictionary *override = [RCTConvert NSDictionary:rule[@"override"]];
188
+
189
+ if (customKeys.count == 0 || override.count == 0) {
190
+ return;
191
+ }
192
+ __block BOOL matches = YES;
193
+ [customKeys enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stopKeys) {
194
+ id actualValue = [content valueForKey:[key description]];
195
+ if (![self matchesCustomKeyActual:actualValue expected:obj]) {
196
+ matches = NO;
197
+ *stopKeys = YES;
198
+ }
199
+ }];
200
+ if (!matches) {
201
+ return;
202
+ }
203
+
204
+ // Basic configuration properties
205
+ if ([override.allKeys containsObject:@"env"]) {
206
+ model.env = [RCTConvert NSString:override[@"env"]];
207
+ }
208
+ if ([override.allKeys containsObject:@"serviceName"]) {
209
+ model.serviceName = [RCTConvert NSString:override[@"serviceName"]];
210
+ }
211
+ if ([override.allKeys containsObject:@"autoSync"]) {
212
+ model.autoSync = @([RCTConvert double:override[@"autoSync"]]);
213
+ }
214
+ if ([override.allKeys containsObject:@"compressIntakeRequests"]) {
215
+ model.compressIntakeRequests = @([RCTConvert double:override[@"compressIntakeRequests"]]);
216
+ }
217
+ if ([override.allKeys containsObject:@"syncPageSize"]) {
218
+ model.syncPageSize = @([RCTConvert double:override[@"syncPageSize"]]);
219
+ }
220
+ if ([override.allKeys containsObject:@"syncSleepTime"]) {
221
+ model.syncSleepTime = @([RCTConvert double:override[@"syncSleepTime"]]);
222
+ }
223
+
224
+ // RUM configuration properties
225
+ if ([override.allKeys containsObject:@"rumSampleRate"]) {
226
+ model.rumSampleRate = @([RCTConvert double:override[@"rumSampleRate"]]);
227
+ }
228
+ if ([override.allKeys containsObject:@"rumSessionOnErrorSampleRate"]) {
229
+ model.rumSessionOnErrorSampleRate = @([RCTConvert double:override[@"rumSessionOnErrorSampleRate"]]);
230
+ }
231
+ if ([override.allKeys containsObject:@"rumEnableTraceUserAction"]) {
232
+ model.rumEnableTraceUserAction = @([RCTConvert double:override[@"rumEnableTraceUserAction"]]);
233
+ }
234
+ if ([override.allKeys containsObject:@"rumEnableTraceUserView"]) {
235
+ model.rumEnableTraceUserView = @([RCTConvert double:override[@"rumEnableTraceUserView"]]);
236
+ }
237
+ if ([override.allKeys containsObject:@"rumEnableTraceUserResource"]) {
238
+ model.rumEnableTraceUserResource = @([RCTConvert double:override[@"rumEnableTraceUserResource"]]);
239
+ }
240
+ if ([override.allKeys containsObject:@"rumEnableResourceHostIP"]) {
241
+ model.rumEnableResourceHostIP = @([RCTConvert double:override[@"rumEnableResourceHostIP"]]);
242
+ }
243
+ if ([override.allKeys containsObject:@"rumEnableTrackAppUIBlock"]) {
244
+ model.rumEnableTrackAppUIBlock = @([RCTConvert double:override[@"rumEnableTrackAppUIBlock"]]);
245
+ }
246
+ if ([override.allKeys containsObject:@"rumBlockDurationMs"]) {
247
+ model.rumBlockDurationMs = @([RCTConvert double:override[@"rumBlockDurationMs"]]);
248
+ }
249
+ if ([override.allKeys containsObject:@"rumEnableTrackAppCrash"]) {
250
+ model.rumEnableTrackAppCrash = @([RCTConvert double:override[@"rumEnableTrackAppCrash"]]);
251
+ }
252
+ if ([override.allKeys containsObject:@"rumEnableTrackAppANR"]) {
253
+ model.rumEnableTrackAppANR = @([RCTConvert double:override[@"rumEnableTrackAppANR"]]);
254
+ }
255
+ if ([override.allKeys containsObject:@"rumEnableTraceWebView"]) {
256
+ model.rumEnableTraceWebView = @([RCTConvert double:override[@"rumEnableTraceWebView"]]);
257
+ }
258
+ if ([override.allKeys containsObject:@"rumAllowWebViewHost"]) {
259
+ model.rumAllowWebViewHost = [RCTConvert NSArray:override[@"rumAllowWebViewHost"]];
260
+ }
261
+
262
+ // Trace configuration properties
263
+ if ([override.allKeys containsObject:@"traceSampleRate"]) {
264
+ model.traceSampleRate = @([RCTConvert double:override[@"traceSampleRate"]]);
265
+ }
266
+ if ([override.allKeys containsObject:@"traceEnableAutoTrace"]) {
267
+ model.traceEnableAutoTrace = @([RCTConvert double:override[@"traceEnableAutoTrace"]]);
268
+ }
269
+ if ([override.allKeys containsObject:@"traceType"]) {
270
+ model.traceType = [RCTConvert NSString:override[@"traceType"]];
271
+ }
272
+
273
+ // Log configuration properties
274
+ if ([override.allKeys containsObject:@"logSampleRate"]) {
275
+ model.logSampleRate = @([RCTConvert double:override[@"logSampleRate"]]);
276
+ }
277
+ if ([override.allKeys containsObject:@"logLevelFilters"]) {
278
+ model.logLevelFilters = [RCTConvert NSArray:override[@"logLevelFilters"]];
279
+ }
280
+ if ([override.allKeys containsObject:@"logEnableCustomLog"]) {
281
+ model.logEnableCustomLog = @([RCTConvert double:override[@"logEnableCustomLog"]]);
282
+ }
283
+
284
+ NSString *ruleId = [RCTConvert NSString:rule[@"id"]];
285
+ [appliedRuleIds addObject:ruleId.length > 0 ? ruleId : [NSString stringWithFormat:@"rule_%lu", (unsigned long)idx]];
286
+ }];
287
+ return appliedRuleIds;
288
+ }
289
+
290
+ RCT_REMAP_METHOD(sdkConfig,
291
+ context:(NSDictionary *)context
292
+ findEventsWithResolver:(RCTPromiseResolveBlock)resolve
293
+ rejecter:(RCTPromiseRejectBlock)reject)
294
+ {
295
+ [self sdkConfig:context resolve:resolve reject:reject];
296
+ }
297
+
298
+ RCT_REMAP_METHOD(setDatakitURL,
299
+ datakitUrl:(NSString *)datakitUrl
300
+ setDatakitURLWithResolver:(RCTPromiseResolveBlock)resolve
301
+ rejecter:(RCTPromiseRejectBlock)reject)
302
+ {
303
+ [self setDatakitURL:datakitUrl resolve:resolve reject:reject];
304
+ }
305
+
306
+ RCT_REMAP_METHOD(setDatawayURL,
307
+ datawayUrl:(NSString *)datawayUrl
308
+ clientToken:(NSString *)clientToken
309
+ setDatawayURLWithResolver:(RCTPromiseResolveBlock)resolve
310
+ rejecter:(RCTPromiseRejectBlock)reject)
311
+ {
312
+ [self setDatawayURL:datawayUrl clientToken:clientToken resolve:resolve reject:reject];
313
+ }
314
+
315
+ RCT_REMAP_METHOD(bindRUMUserData,
316
+ userId:(NSString*)userId userName:(NSString*)userName userEmail:(NSString*)userEmail extra:(NSDictionary *)extra
317
+ findEventsWithResolver:(RCTPromiseResolveBlock)resolve
318
+ rejecter:(RCTPromiseRejectBlock)reject){
319
+ [self bindRUMUserData:userId userName:userName userEmail:userName extra:extra resolve:resolve reject:reject];
320
+ }
321
+
322
+ RCT_REMAP_METHOD(unbindRUMUserData,
323
+ unbindRUMUserData_Resolver:(RCTPromiseResolveBlock)resolve
324
+ rejecter:(RCTPromiseRejectBlock)reject
325
+ ){
326
+ [self unbindRUMUserData:resolve reject:reject];
327
+ }
328
+ RCT_REMAP_METHOD(appendGlobalContext,
329
+ appendGlobalContext:(NSDictionary *)context
330
+ findEventsWithResolver:(RCTPromiseResolveBlock)resolve
331
+ rejecter:(RCTPromiseRejectBlock)reject){
332
+ [self appendGlobalContext:context resolve:resolve reject:reject];
333
+ }
334
+ RCT_REMAP_METHOD(appendRUMGlobalContext,
335
+ appendRUMGlobalContext:(NSDictionary *)context
336
+ findEventsWithResolver:(RCTPromiseResolveBlock)resolve
337
+ rejecter:(RCTPromiseRejectBlock)reject){
338
+ [self appendRUMGlobalContext:context resolve:resolve reject:reject];
339
+ }
340
+ RCT_REMAP_METHOD(appendLogGlobalContext,
341
+ appendLogGlobalContext:(NSDictionary *)context
342
+ findEventsWithResolver:(RCTPromiseResolveBlock)resolve
343
+ rejecter:(RCTPromiseRejectBlock)reject){
344
+ [self appendLogGlobalContext:context resolve:resolve reject:reject];
345
+ }
346
+
347
+ RCT_REMAP_METHOD(flushSyncData,
348
+ flushSyncData_Resolver:(RCTPromiseResolveBlock)resolve
349
+ rejecter:(RCTPromiseRejectBlock)reject
350
+ ){
351
+ [self flushSyncData:resolve reject:reject];
352
+ }
353
+ RCT_REMAP_METHOD(trackEventFromExtension,
354
+ identifier:(NSString*)identifier
355
+ findEventsWithResolver:(RCTPromiseResolveBlock)resolve
356
+ rejecter:(RCTPromiseRejectBlock)reject){
357
+ [self trackEventFromExtension:identifier resolve:resolve reject:reject];
358
+ }
359
+ RCT_REMAP_METHOD(shutDown,
360
+ shutDown_findEventsWithResolver:(RCTPromiseResolveBlock)resolve
361
+ rejecter:(RCTPromiseRejectBlock)reject){
362
+ [self shutDown:resolve reject:reject];
363
+ }
364
+ RCT_REMAP_METHOD(clearAllData,
365
+ clearAllData_findEventsWithResolver:(RCTPromiseResolveBlock)resolve
366
+ rejecter:(RCTPromiseRejectBlock)reject){
367
+ [self clearAllData:resolve reject:reject];
368
+ }
369
+ #ifdef RCT_NEW_ARCH_ENABLED
370
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params {
371
+ return std::make_shared<facebook::react::NativeFTMobileReactNativeSpecJSI>(params);
372
+ }
373
+ #endif
374
+ - (void)sdkConfig:(NSDictionary *)context resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
375
+ [FTThreadDispatchManager performBlockDispatchMainSyncSafe:^{
376
+ FTMobileConfig *config;
377
+ NSString *datakitUrl = [RCTConvert NSString:context[@"datakitUrl"]];
378
+ NSString *dataWayUrl = [RCTConvert NSString:context[@"datawayUrl"]];
379
+ NSString *clientToken = [RCTConvert NSString:context[@"clientToken"]];
380
+ if(dataWayUrl && dataWayUrl.length>0 && clientToken && clientToken.length>0){
381
+ config = [[FTMobileConfig alloc]initWithDatawayUrl:dataWayUrl clientToken:clientToken];
382
+ }else if(datakitUrl && datakitUrl.length>0){
383
+ config = [[FTMobileConfig alloc]initWithDatakitUrl:datakitUrl];
384
+ }else{
385
+ resolve(nil);
386
+ return;
387
+ }
388
+ if ([context.allKeys containsObject:@"debug"]) {
389
+ config.enableSDKDebugLog = [RCTConvert BOOL:context[@"debug"]];
390
+ }
391
+ if ([context.allKeys containsObject:@"service"]) {
392
+ config.service = [RCTConvert NSString:context[@"service"]];
393
+ }
394
+ if([context.allKeys containsObject:@"env"]){
395
+ id env = context[@"env"];
396
+ if([env isKindOfClass:NSString.class]){
397
+ config.env = env;
398
+ }
399
+ }
400
+ if([context.allKeys containsObject:@"envType"]){
401
+ id env = context[@"envType"];
402
+ if([env isKindOfClass:NSNumber.class]){
403
+ int envType = [env intValue];
404
+ if(envType>=0 && envType<5){
405
+ [config setEnvWithType:(FTEnv)envType];
406
+ }
407
+ }
408
+ }
409
+ if ([context.allKeys containsObject:@"autoSync"]) {
410
+ config.autoSync = [RCTConvert BOOL:context[@"autoSync"]];
411
+ }
412
+ if ([context.allKeys containsObject:@"syncPageSize"]) {
413
+ config.syncPageSize = [RCTConvert int:context[@"syncPageSize"]];
414
+ }
415
+ if ([context.allKeys containsObject:@"syncSleepTime"]) {
416
+ config.syncSleepTime = [RCTConvert int:context[@"syncSleepTime"]];
417
+ }
418
+ if ([context.allKeys containsObject:@"enableDataIntegerCompatible"]) {
419
+ config.enableDataIntegerCompatible = [RCTConvert BOOL:context[@"enableDataIntegerCompatible"]];
420
+ }
421
+ if ([context.allKeys containsObject:@"compressIntakeRequests"]) {
422
+ config.compressIntakeRequests = [RCTConvert BOOL:context[@"compressIntakeRequests"]];
423
+ }
424
+ if ([context.allKeys containsObject:@"globalContext"]) {
425
+ config.globalContext = [RCTConvert NSDictionary:context[@"globalContext"]];
426
+ }
427
+ if ([context.allKeys containsObject:@"groupIdentifiers"]){
428
+ config.groupIdentifiers = [RCTConvert NSArray:context[@"groupIdentifiers"]];
429
+ }
430
+ if ([context.allKeys containsObject:@"dbDiscardStrategy"]){
431
+ config.dbDiscardType = (FTDBCacheDiscard)[RCTConvert int:context[@"dbDiscardStrategy"]];
432
+ }
433
+ if ([context.allKeys containsObject:@"enableLimitWithDbSize"]){
434
+ config.enableLimitWithDbSize = [RCTConvert BOOL:context[@"enableLimitWithDbSize"]];
435
+ }
436
+ if ([context.allKeys containsObject:@"dbCacheLimit"]){
437
+ config.dbCacheLimit = (long)[RCTConvert double:context[@"dbCacheLimit"]];
438
+ }
439
+ if ([context.allKeys containsObject:@"dataModifier"]){
440
+ NSDictionary *dataModifierDict = [[RCTConvert NSDictionary:context[@"dataModifier"]] copy];
441
+ config.dataModifier = ^id _Nullable(NSString * _Nonnull key, id _Nonnull value) {
442
+ if ([dataModifierDict.allKeys containsObject:key]) {
443
+ return dataModifierDict[key];
444
+ }
445
+ return value;
446
+ };
447
+ }
448
+ if ([context.allKeys containsObject:@"lineDataModifier"]){
449
+ NSDictionary *dataModifierDict = [[RCTConvert NSDictionary:context[@"lineDataModifier"]] copy];
450
+ config.lineDataModifier = ^NSDictionary<NSString *,id> * _Nullable(NSString * _Nonnull measurement, NSDictionary<NSString *,id> * _Nonnull data) {
451
+ if ([measurement isEqualToString:FT_LOGGER_SOURCE] || [measurement isEqualToString:FT_LOGGER_TVOS_SOURCE]) {
452
+ return [dataModifierDict valueForKey:@"log"];
453
+ }else{
454
+ return [dataModifierDict valueForKey:measurement];
455
+ }
456
+ };
457
+ }
458
+ if ([context.allKeys containsObject:@"remoteConfiguration"]){
459
+ config.remoteConfiguration = [RCTConvert BOOL:context[@"remoteConfiguration"]];
460
+ }
461
+ if ([context.allKeys containsObject:@"remoteConfigMiniUpdateInterval"]){
462
+ config.remoteConfigMiniUpdateInterval = [RCTConvert int:context[@"remoteConfigMiniUpdateInterval"]];
463
+ }
464
+ _remoteConfigOverrideRules = [RCTConvert NSArray:context[@"remoteConfigOverrideRules"]];
465
+ _remoteConfigurationEnabled = config.remoteConfiguration;
466
+ _remoteConfigMiniUpdateInterval = config.remoteConfigMiniUpdateInterval;
467
+ if (config.remoteConfiguration) {
468
+ __weak __typeof(self) weakSelf = self;
469
+ config.remoteConfigFetchCompletionBlock = ^FTRemoteConfigModel * _Nullable(BOOL success, NSError * _Nullable error, FTRemoteConfigModel * _Nullable model, NSDictionary<NSString *,id> * _Nullable content) {
470
+ __typeof(self) strongSelf = weakSelf;
471
+ if (!strongSelf) {
472
+ return nil;
473
+ }
474
+ @try {
475
+ NSArray<NSString *> *appliedRuleIds = [strongSelf applyRemoteConfigOverrideRulesWithModel:model content:content rules:strongSelf->_remoteConfigOverrideRules];
476
+ [strongSelf emitAutoRemoteConfigEventWithSuccess:success content:content error:error model:model];
477
+ if (appliedRuleIds.count > 0) {
478
+ return model;
479
+ }
480
+ } @catch (NSException *exception) {
481
+ [strongSelf emitAutoRemoteConfigEventWithSuccess:NO content:nil error:nil model:nil];
482
+ }
483
+ return nil;
484
+ };
485
+ }
486
+ [FTMobileAgent startWithConfigOptions:config];
487
+ resolve(nil);
488
+ }];
489
+ }
490
+ - (void)setDatakitURL:(NSString *)datakitUrl resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
491
+ [FTMobileAgent setDatakitURL:datakitUrl];
492
+ resolve(nil);
493
+ }
494
+
495
+ - (void)setDatawayURL:(NSString *)datawayUrl clientToken:(NSString *)clientToken resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
496
+ [FTMobileAgent setDatawayURL:datawayUrl clientToken:clientToken];
497
+ resolve(nil);
498
+ }
499
+
500
+ - (void)appendGlobalContext:(NSDictionary *)context resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
501
+ [FTMobileAgent appendGlobalContext:context];
502
+ resolve(nil);
503
+ }
504
+
505
+ - (void)appendLogGlobalContext:(NSDictionary *)context resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
506
+ [FTMobileAgent appendLogGlobalContext:context];
507
+ resolve(nil);
508
+ }
509
+
510
+ - (void)appendRUMGlobalContext:(NSDictionary *)context resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
511
+ [FTMobileAgent appendRUMGlobalContext:context];
512
+ resolve(nil);
513
+ }
514
+
515
+ - (void)bindRUMUserData:(NSString *)userId userName:(NSString *)userName userEmail:(NSString *)userEmail extra:(NSDictionary *)extra resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
516
+ [[FTMobileAgent sharedInstance] bindUserWithUserID:userId userName:userName userEmail:userEmail extra:extra];
517
+ resolve(nil);
518
+ }
519
+ - (void)unbindRUMUserData:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
520
+ [[FTMobileAgent sharedInstance] unbindUser];
521
+ resolve(nil);
522
+ }
523
+ - (void)clearAllData:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
524
+ [FTMobileAgent clearAllData];
525
+ resolve(nil);
526
+ }
527
+
528
+ - (void)flushSyncData:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
529
+ [[FTMobileAgent sharedInstance] flushSyncData];
530
+ resolve(nil);
531
+ }
532
+
533
+ - (void)shutDown:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
534
+ [FTMobileAgent shutDown];
535
+ resolve(nil);
536
+ }
537
+
538
+ - (void)trackEventFromExtension:(NSString *)identifier resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
539
+ [[FTMobileAgent sharedInstance] trackEventFromExtensionWithGroupIdentifier:identifier completion:^(NSString * _Nonnull groupIdentifier, NSArray * _Nonnull events) {
540
+ if(events.count>0){
541
+ resolve(@{@"groupIdentifier":identifier,
542
+ @"datas":events
543
+ });
544
+ }else{
545
+ resolve(nil);
546
+ }
547
+
548
+ }];
549
+ }
550
+ RCT_REMAP_METHOD(updateRemoteConfig,
551
+ updateRemoteConfig_findEventsWithResolver:(RCTPromiseResolveBlock)resolve
552
+ rejecter:(RCTPromiseRejectBlock)reject){
553
+ if (!_remoteConfigurationEnabled) {
554
+ reject(@"E_REMOTE_CONFIG_DISABLED", @"Remote configuration is not enabled.", nil);
555
+ return;
556
+ }
557
+ [FTMobileAgent updateRemoteConfigWithMiniUpdateInterval:_remoteConfigMiniUpdateInterval completion:^FTRemoteConfigModel * _Nullable(BOOL success, NSError * _Nullable error, FTRemoteConfigModel * _Nullable model, NSDictionary<NSString *,id> * _Nullable content) {
558
+ @try {
559
+ NSDictionary *result = [self remoteConfigResultWithSuccess:success content:content error:error triggerType:@"manual" model:model rules:nil];
560
+ if (success) {
561
+ resolve(result);
562
+ } else {
563
+ NSString *message = error.localizedDescription ?: @"Remote config update failed.";
564
+ reject(@"E_REMOTE_CONFIG_UPDATE_FAILED", message, error);
565
+ }
566
+ NSArray<NSString *> *appliedRuleIds = result[@"appliedOverrideRuleIds"];
567
+ if (appliedRuleIds.count > 0) {
568
+ return model;
569
+ }
570
+ } @catch (NSException *exception) {
571
+ NSString *message = [NSString stringWithFormat:@"Exception occurred: %@", exception];
572
+ reject(@"E_REMOTE_CONFIG_EXCEPTION", message, nil);
573
+ }
574
+ return nil;
575
+ }];
576
+ }
577
+ RCT_REMAP_METHOD(updateRemoteConfigWithMiniUpdateInterval,
578
+ interval:(int)interval
579
+ rules:(NSArray *)rules
580
+ findEventsWithResolver:(RCTPromiseResolveBlock)resolve
581
+ rejecter:(RCTPromiseRejectBlock)reject){
582
+ if (!_remoteConfigurationEnabled) {
583
+ reject(@"E_REMOTE_CONFIG_DISABLED", @"Remote configuration is not enabled.", nil);
584
+ return;
585
+ }
586
+ __weak __typeof(self) weakSelf = self;
587
+ [FTMobileAgent updateRemoteConfigWithMiniUpdateInterval:(NSInteger)interval completion:^FTRemoteConfigModel * _Nullable(BOOL success, NSError * _Nullable error, FTRemoteConfigModel * _Nullable model, NSDictionary<NSString *,id> * _Nullable content) {
588
+ __typeof(self) strongSelf = weakSelf;
589
+ if (!strongSelf) {
590
+ return nil;
591
+ }
592
+ @try {
593
+ NSArray<NSDictionary *> *rulesToApply = nil;
594
+ if (rules != nil && ![rules isKindOfClass:[NSNull class]]) {
595
+ rulesToApply = [RCTConvert NSArray:rules];
596
+ }
597
+ if (rulesToApply == nil || rulesToApply.count == 0) {
598
+ rulesToApply = strongSelf->_remoteConfigOverrideRules;
599
+ }
600
+ NSDictionary *result = [strongSelf remoteConfigResultWithSuccess:success content:content error:error triggerType:@"manual" model:model rules:rulesToApply];
601
+ if (success) {
602
+ resolve(result);
603
+ } else {
604
+ NSString *message = error.localizedDescription ?: @"Remote config update failed.";
605
+ reject(@"E_REMOTE_CONFIG_UPDATE_FAILED", message, error);
606
+ }
607
+ NSArray<NSString *> *appliedRuleIds = result[@"appliedOverrideRuleIds"];
608
+ if (appliedRuleIds.count > 0) {
609
+ return model;
610
+ }
611
+ } @catch (NSException *exception) {
612
+ NSString *message = [NSString stringWithFormat:@"Exception occurred: %@", exception];
613
+ reject(@"E_REMOTE_CONFIG_EXCEPTION", message, nil);
614
+ }
615
+ return nil;
616
+ }];
617
+ }
618
+
619
+ @end
@@ -9,10 +9,15 @@
9
9
  #import <Foundation/Foundation.h>
10
10
  #import <React/RCTBridgeModule.h>
11
11
 
12
- NS_ASSUME_NONNULL_BEGIN
13
12
 
14
- @interface FTReactNativeLog : NSObject<RCTBridgeModule>
13
+ #ifdef RCT_NEW_ARCH_ENABLED
14
+ #import <FTSdkReactNative/FTSdkReactNative.h>
15
+ @interface FTReactNativeLog: NSObject <NativeFTReactNativeLogSpec>
16
+ #else
17
+
18
+ #import <React/RCTBridgeModule.h>
19
+ @interface FTReactNativeLog : NSObject <RCTBridgeModule>
20
+ #endif
15
21
 
16
22
  @end
17
23
 
18
- NS_ASSUME_NONNULL_END