react-native-userleap 4.0.0 → 4.1.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.
@@ -15,9 +15,16 @@ Pod::Spec.new do |s|
15
15
  s.platforms = { :ios => "15.0" }
16
16
  s.source = { :git => "https://github.com/github_account/react-native-userleap.git", :tag => "#{s.version}" }
17
17
 
18
- s.source_files = "ios/**/*.{h,c,m,swift}"
18
+ s.source_files = "ios/**/*.{h,c,m,mm,swift}"
19
19
  s.requires_arc = true
20
20
 
21
- s.dependency "React"
22
- s.dependency "UserLeapKit", "4.32.3"
21
+ s.dependency "UserLeapKit", "4.33.0"
22
+
23
+ # New Architecture: wires up the React-Codegen dependency and header search
24
+ # paths so the generated RNUserLeapBindingsSpec (Obj-C++) resolves.
25
+ if respond_to?(:install_modules_dependencies, true)
26
+ install_modules_dependencies(s)
27
+ else
28
+ s.dependency "React-Core"
29
+ end
23
30
  end
@@ -0,0 +1,95 @@
1
+ /**
2
+ * TurboModule spec for the react-native-userleap native bridge.
3
+ * Events use a single onSprigEvent channel carrying a {name, json} JSON-string
4
+ * envelope, because event payloads are heterogeneous.
5
+ */
6
+
7
+ import type {TurboModule, TurboModuleRegistry, CodegenTypes} from 'react-native';
8
+
9
+ /** Result payload for the modern trackEvent* family. */
10
+ export type SurveyResult = {
11
+ surveyState: string;
12
+ surveyId: number;
13
+ };
14
+
15
+ /** Envelope for the lifecycle-event channel: event name plus JSON-stringified payload. */
16
+ export type SprigEventPayload = {
17
+ name: string;
18
+ json: string;
19
+ };
20
+
21
+ export interface Spec extends TurboModule {
22
+ visitorIdentifier(): number;
23
+ visitorIdentifierString(): string;
24
+ getSdkVersion(): string;
25
+
26
+ configure(environmentId: string, configuration: Object): void;
27
+ setPreviewKey(previewKey: string): void;
28
+ setUserIdentifier(identifier: string): void;
29
+ setEmailAddress(emailAddress: string): void;
30
+ logout(): void;
31
+
32
+ setVisitorAttribute(key: string, value: string): void;
33
+ setVisitorAttributes(attributes: Object): void;
34
+ removeVisitorAttributes(keys: Array<string>): void;
35
+ setVisitorAttributesAndIdentify(
36
+ attributes: Object,
37
+ userId: string | null,
38
+ partnerAnonymousId: string | null,
39
+ ): void;
40
+
41
+ presentSurvey(): void;
42
+ dismissActiveSurvey(): void;
43
+ pauseDisplayingSurveys(): void;
44
+ unpauseDisplayingSurveys(): void;
45
+ trackAndPresent(eventName: string): void;
46
+ trackIdentifyAndPresent(
47
+ eventName: string,
48
+ userId: string | null,
49
+ partnerAnonymousId: string | null,
50
+ ): void;
51
+ overrideUserInterfaceMode(mode: number): void;
52
+
53
+ trackEvent(
54
+ eventName: string,
55
+ surveyResultCallback: (result: SurveyResult) => void,
56
+ ): void;
57
+ trackEventWithProperties(
58
+ eventName: string,
59
+ userId: string | null,
60
+ partnerAnonymousId: string | null,
61
+ properties: Object,
62
+ surveyResultCallback: (result: SurveyResult) => void,
63
+ ): void;
64
+ trackEventAndIdentify(
65
+ eventName: string,
66
+ userId: string | null,
67
+ partnerAnonymousId: string | null,
68
+ surveyResultCallback: (result: SurveyResult) => void,
69
+ ): void;
70
+
71
+ // Deprecated; use trackEvent* instead.
72
+ track(
73
+ eventName: string,
74
+ surveyStateCallback: (surveyState: string) => void,
75
+ ): void;
76
+ trackWithProperties(
77
+ eventName: string,
78
+ userId: string | null,
79
+ partnerAnonymousId: string | null,
80
+ properties: Object,
81
+ surveyStateCallback: (surveyState: string) => void,
82
+ ): void;
83
+ trackAndIdentify(
84
+ eventName: string,
85
+ userId: string | null,
86
+ partnerAnonymousId: string | null,
87
+ surveyStateCallback: (surveyState: string) => void,
88
+ ): void;
89
+
90
+ readonly onSprigEvent: CodegenTypes.EventEmitter<SprigEventPayload>;
91
+
92
+ getSupportedEventNames(): Array<string>;
93
+ }
94
+
95
+ export default TurboModuleRegistry.getEnforcing<Spec>('UserLeapBindings');
@@ -1,387 +0,0 @@
1
- package com.userleap.reactnative;
2
-
3
- import android.app.Activity;
4
- import android.util.Log;
5
-
6
- import androidx.fragment.app.FragmentActivity;
7
-
8
- import com.facebook.react.bridge.Arguments;
9
- import com.facebook.react.bridge.Callback;
10
- import com.facebook.react.bridge.ReactApplicationContext;
11
- import com.facebook.react.bridge.ReactContextBaseJavaModule;
12
- import com.facebook.react.bridge.ReactMethod;
13
- import com.facebook.react.bridge.ReadableArray;
14
- import com.facebook.react.bridge.ReadableMap;
15
- import com.facebook.react.bridge.WritableMap;
16
- import com.userleap.EventListener;
17
- import com.userleap.EventName;
18
- import com.userleap.EventPayload;
19
- import com.userleap.SprigEvent;
20
- import com.userleap.SprigSurveyResult;
21
- import com.userleap.SurveyState;
22
- import com.userleap.UserLeap;
23
- import com.userleap.SprigUserInterfaceMode;
24
-
25
- import org.json.JSONException;
26
- import org.json.JSONObject;
27
-
28
- import java.util.HashMap;
29
- import java.util.Iterator;
30
- import java.util.List;
31
- import java.util.Map;
32
- import java.util.Objects;
33
- import java.util.stream.Collectors;
34
-
35
- import javax.annotation.Nullable;
36
-
37
- import kotlin.Unit;
38
- import kotlin.jvm.functions.Function1;
39
-
40
- public class UserLeapModule extends ReactContextBaseJavaModule {
41
-
42
- private static final String TAG = "UserLeapModule";
43
-
44
- private final ReactApplicationContext reactContext;
45
-
46
- public UserLeapModule(ReactApplicationContext reactContext) {
47
- super(reactContext);
48
- this.reactContext = reactContext;
49
- }
50
-
51
- @Override
52
- public String getName() {
53
- return "UserLeapBindings";
54
- }
55
-
56
- // ---------------------------------------------------------------------------
57
- // Bridge helpers
58
- // ---------------------------------------------------------------------------
59
-
60
- /**
61
- * Converts UPPER_SNAKE_CASE to camelCase to match the iOS event naming
62
- * convention expected by the JS layer.
63
- * e.g. "SURVEY_WILL_PRESENT" -> "surveyWillPresent"
64
- */
65
- private String toCamelCase(String upperSnakeCase) {
66
- String[] parts = upperSnakeCase.toLowerCase().split("_");
67
- StringBuilder sb = new StringBuilder(parts[0]);
68
- for (int i = 1; i < parts.length; i++) {
69
- sb.append(Character.toUpperCase(parts[i].charAt(0)));
70
- sb.append(parts[i].substring(1));
71
- }
72
- return sb.toString();
73
- }
74
-
75
- /**
76
- * Shallow-converts a JSONObject to a WritableMap for passing across the RN bridge.
77
- */
78
- private WritableMap jsonObjectToWritableMap(@Nullable JSONObject json) {
79
- WritableMap map = Arguments.createMap();
80
- if (json == null) {
81
- return map;
82
- }
83
- Iterator<String> keys = json.keys();
84
- while (keys.hasNext()) {
85
- String key = keys.next();
86
- try {
87
- Object value = json.get(key);
88
- if (value instanceof String) {
89
- map.putString(key, (String) value);
90
- } else if (value instanceof Boolean) {
91
- map.putBoolean(key, (Boolean) value);
92
- } else if (value instanceof Integer) {
93
- map.putInt(key, (Integer) value);
94
- } else if (value instanceof Double) {
95
- map.putDouble(key, (Double) value);
96
- } else if (value instanceof JSONObject) {
97
- map.putMap(key, jsonObjectToWritableMap((JSONObject) value));
98
- } else if (value == JSONObject.NULL) {
99
- map.putNull(key);
100
- } else {
101
- map.putString(key, value.toString());
102
- }
103
- } catch (JSONException e) {
104
- Log.w(TAG, "Failed to convert key '" + key + "' from SprigEvent data", e);
105
- }
106
- }
107
- return map;
108
- }
109
-
110
- /**
111
- * Converts a SprigSurveyResult to a WritableMap for passing across the RN bridge.
112
- * Returns { surveyState: string, surveyId: int }
113
- */
114
- private WritableMap surveyResultToWritableMap(SprigSurveyResult surveyResult) {
115
- WritableMap resultMap = Arguments.createMap();
116
- resultMap.putString("surveyState", surveyResult.getSurveyState().name());
117
- resultMap.putInt("surveyId", surveyResult.getSurveyId());
118
- return resultMap;
119
- }
120
-
121
- /**
122
- * Wraps a RN Callback as a Function1<SprigSurveyResult, Unit> for the EventPayload API.
123
- * Returns null if the callback is null.
124
- */
125
- private @Nullable Function1<SprigSurveyResult, Unit> wrapResultCallback(@Nullable final Callback callback) {
126
- if (callback == null) {
127
- return null;
128
- }
129
- return new Function1<SprigSurveyResult, Unit>() {
130
- @Override
131
- public Unit invoke(SprigSurveyResult surveyResult) {
132
- callback.invoke(surveyResultToWritableMap(surveyResult));
133
- return null;
134
- }
135
- };
136
- }
137
-
138
- private Map<String, String> stringifyMap(ReadableMap map) {
139
- Map<String, String> stringifiedMap = new HashMap<>();
140
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
141
- stringifiedMap = map.toHashMap().entrySet().stream()
142
- .filter(m -> m.getKey() != null && m.getValue() != null)
143
- .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().toString()));
144
- }
145
- return stringifiedMap;
146
- }
147
-
148
- private @Nullable FragmentActivity getFragmentActivity() {
149
- Activity activity = getCurrentActivity();
150
- if (activity instanceof FragmentActivity) {
151
- return (FragmentActivity) activity;
152
- } else {
153
- return null;
154
- }
155
- }
156
-
157
- // ---------------------------------------------------------------------------
158
- // SDK properties
159
- // ---------------------------------------------------------------------------
160
-
161
- @ReactMethod(isBlockingSynchronousMethod = true)
162
- public int visitorIdentifier() {
163
- final Integer visitorIdentifierObject = UserLeap.INSTANCE.getVisitorIdentifier();
164
- return visitorIdentifierObject == null ? 0 : visitorIdentifierObject;
165
- }
166
-
167
- @ReactMethod(isBlockingSynchronousMethod = true)
168
- public String visitorIdentifierString() {
169
- final String visitorIdentifierObject = UserLeap.INSTANCE.getVisitorIdentifierString();
170
- return visitorIdentifierObject == null ? "" : visitorIdentifierObject;
171
- }
172
-
173
- @ReactMethod(isBlockingSynchronousMethod = true)
174
- public String getSdkVersion() {
175
- return UserLeap.INSTANCE.getSdkVersion();
176
- }
177
-
178
- // ---------------------------------------------------------------------------
179
- // Configuration
180
- // ---------------------------------------------------------------------------
181
-
182
- @ReactMethod
183
- public void configure(String environment, ReadableMap configuration) {
184
- UserLeap.INSTANCE.addEventListener(EventName.LOGGING_EVENT, new EventListener() {
185
- @Override
186
- public void onEvent(SprigEvent event) {
187
- String tag = "SprigLoggingEvent";
188
- switch (event.getLogLevel()) {
189
- case INFO:
190
- Log.i(tag, event.getLogMessage());
191
- break;
192
- case DEBUG:
193
- Log.d(tag, event.getLogMessage());
194
- break;
195
- case WARNING:
196
- Log.w(tag, event.getLogMessage());
197
- break;
198
- case ERROR:
199
- case CRITICAL:
200
- Log.e(tag, event.getLogMessage());
201
- break;
202
- }
203
- }
204
- });
205
-
206
- UserLeap.INSTANCE.configure(
207
- reactContext,
208
- environment,
209
- stringifyMap(configuration),
210
- getFragmentActivity()
211
- );
212
- }
213
-
214
- // ---------------------------------------------------------------------------
215
- // Deprecated track methods (return SurveyState string)
216
- // ---------------------------------------------------------------------------
217
-
218
- @ReactMethod
219
- public void track(String event, final Callback surveyStateCallback) {
220
- trackAndIdentify(event, null, null, surveyStateCallback);
221
- }
222
-
223
- @ReactMethod
224
- public void trackWithProperties(String event, String userId, String partnerAnonymousId, ReadableMap properties, final Callback surveyStateCallback) {
225
- if (surveyStateCallback == null) {
226
- UserLeap.INSTANCE.track(event, userId, partnerAnonymousId, stringifyMap(properties));
227
- } else {
228
- UserLeap.INSTANCE.track(event, userId, partnerAnonymousId, stringifyMap(properties), new Function1<SurveyState, Unit>() {
229
- @Override
230
- public Unit invoke(SurveyState surveyState) {
231
- surveyStateCallback.invoke(surveyState.name());
232
- return null;
233
- }
234
- });
235
- }
236
- }
237
-
238
- @ReactMethod
239
- public void trackAndIdentify(String event, String userId, String partnerAnonymousId, final Callback surveyStateCallback) {
240
- if (surveyStateCallback == null) {
241
- UserLeap.INSTANCE.track(event, userId, partnerAnonymousId);
242
- } else {
243
- UserLeap.INSTANCE.track(event, userId, partnerAnonymousId, new Function1<SurveyState, Unit>() {
244
- @Override
245
- public Unit invoke(SurveyState surveyState) {
246
- surveyStateCallback.invoke(surveyState.name());
247
- return null;
248
- }
249
- });
250
- }
251
- }
252
-
253
- // ---------------------------------------------------------------------------
254
- // New track methods (return SprigSurveyResult via EventPayload)
255
- // ---------------------------------------------------------------------------
256
-
257
- @ReactMethod
258
- public void trackEvent(String event, final Callback surveyStateCallback) {
259
- trackEventAndIdentify(event, null, null, surveyStateCallback);
260
- }
261
-
262
- @ReactMethod
263
- public void trackEventWithProperties(String event, String userId, String partnerAnonymousId, ReadableMap properties, final Callback surveyStateCallback) {
264
- EventPayload payload = new EventPayload(
265
- event,
266
- userId,
267
- partnerAnonymousId,
268
- stringifyMap(properties),
269
- wrapResultCallback(surveyStateCallback),
270
- null, // shouldShowSurveyCallback
271
- null // deprecated callback
272
- );
273
- UserLeap.INSTANCE.track(payload);
274
- }
275
-
276
- @ReactMethod
277
- public void trackEventAndIdentify(String event, String userId, String partnerAnonymousId, final Callback surveyStateCallback) {
278
- EventPayload payload = new EventPayload(
279
- event,
280
- userId,
281
- partnerAnonymousId,
282
- null, // properties
283
- wrapResultCallback(surveyStateCallback),
284
- null, // shouldShowSurveyCallback
285
- null // deprecated callback
286
- );
287
- UserLeap.INSTANCE.track(payload);
288
- }
289
-
290
- // ---------------------------------------------------------------------------
291
- // Track and present
292
- // ---------------------------------------------------------------------------
293
-
294
- @ReactMethod
295
- public void trackAndPresent(String event) {
296
- UserLeap.INSTANCE.trackAndPresent(event, getFragmentActivity());
297
- }
298
-
299
- @ReactMethod
300
- public void trackIdentifyAndPresent(String event, String userId, String partnerAnonymousId) {
301
- UserLeap.INSTANCE.trackAndPresent(event, userId, partnerAnonymousId, getFragmentActivity());
302
- }
303
-
304
- // ---------------------------------------------------------------------------
305
- // Survey presentation
306
- // ---------------------------------------------------------------------------
307
-
308
- @ReactMethod
309
- public void presentSurvey() {
310
- UserLeap.INSTANCE.presentSurvey(null);
311
- }
312
-
313
- @ReactMethod
314
- public void dismissActiveSurvey() {
315
- UserLeap.INSTANCE.dismissActiveSurvey();
316
- }
317
-
318
- @ReactMethod
319
- public void pauseDisplayingSurveys() {
320
- UserLeap.INSTANCE.pauseDisplayingSurveys();
321
- }
322
-
323
- @ReactMethod
324
- public void unpauseDisplayingSurveys() {
325
- UserLeap.INSTANCE.unpauseDisplayingSurveys();
326
- }
327
-
328
- // ---------------------------------------------------------------------------
329
- // User identity & attributes
330
- // ---------------------------------------------------------------------------
331
-
332
- @ReactMethod
333
- public void setEmailAddress(String emailAddress) {
334
- UserLeap.INSTANCE.setEmailAddress(emailAddress);
335
- }
336
-
337
- @ReactMethod
338
- public void setVisitorAttribute(String key, String value) {
339
- UserLeap.INSTANCE.setVisitorAttribute(key, value);
340
- }
341
-
342
- @ReactMethod
343
- public void setVisitorAttributes(ReadableMap attributes) {
344
- UserLeap.INSTANCE.setVisitorAttributes(stringifyMap(attributes));
345
- }
346
-
347
- @ReactMethod
348
- public void setVisitorAttributesAndIdentify(ReadableMap attributes, String userId, String partnerAnonymousId) {
349
- UserLeap.INSTANCE.setVisitorAttributes(stringifyMap(attributes), userId, partnerAnonymousId);
350
- }
351
-
352
- @ReactMethod
353
- public void removeVisitorAttributes(ReadableArray attributes) {
354
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
355
- List<String> attributeStrings = attributes.toArrayList().stream()
356
- .map(object -> Objects.toString(object, null))
357
- .collect(Collectors.toList());
358
- UserLeap.INSTANCE.removeVisitorAttributes(attributeStrings);
359
- }
360
- }
361
-
362
- @ReactMethod
363
- public void setPreviewKey(String previewKey) {
364
- UserLeap.INSTANCE.setPreviewKey(previewKey);
365
- }
366
-
367
- @ReactMethod
368
- public void setUserIdentifier(String identifier) {
369
- UserLeap.INSTANCE.setUserIdentifier(identifier);
370
- }
371
-
372
- @ReactMethod
373
- public void overrideUserInterfaceMode(double mode) {
374
- int modeInt = (int) mode;
375
- for (SprigUserInterfaceMode m : SprigUserInterfaceMode.values()) {
376
- if (m.getValue() == modeInt) {
377
- UserLeap.INSTANCE.overrideUserInterfaceMode(m);
378
- return;
379
- }
380
- }
381
- }
382
-
383
- @ReactMethod
384
- public void logout() {
385
- UserLeap.INSTANCE.logout();
386
- }
387
- }