react-native-uxrate 0.2.1 → 0.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.
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/uxrate/reactnative/UXRateModule.kt +13 -14
- package/docs/public/api-reference.md +5 -3
- package/docs/public/event-tracking.md +7 -25
- package/docs/public/quick-start.md +9 -1
- package/docs/public/replay-config.md +8 -22
- package/example/App.tsx +3 -6
- package/index.d.ts +2 -1
- package/index.js +6 -49
- package/ios/UXRateModule.m +65 -30
- package/ios/UXRateModule.swift +23 -59
- package/package.json +1 -1
- package/react-native-uxrate.podspec +1 -1
package/android/build.gradle
CHANGED
|
@@ -3,18 +3,10 @@ package com.uxrate.reactnative
|
|
|
3
3
|
import android.app.Application
|
|
4
4
|
import com.facebook.react.bridge.*
|
|
5
5
|
import com.uxrate.sdk.UXRate
|
|
6
|
+
import com.uxrate.sdk.models.Environment
|
|
6
7
|
import com.uxrate.sdk.models.OverlapStrategy
|
|
7
8
|
import com.uxrate.sdk.models.SDKTheme
|
|
8
9
|
|
|
9
|
-
/**
|
|
10
|
-
* React Native native module for the UXRate Android SDK.
|
|
11
|
-
*
|
|
12
|
-
* Exposes the same 4 methods as the iOS module:
|
|
13
|
-
* - configure(apiKey, options)
|
|
14
|
-
* - identify(userId, properties)
|
|
15
|
-
* - track(event)
|
|
16
|
-
* - setScreen(name)
|
|
17
|
-
*/
|
|
18
10
|
class UXRateModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
|
19
11
|
|
|
20
12
|
override fun getName(): String = "UXRate"
|
|
@@ -32,9 +24,16 @@ class UXRateModule(reactContext: ReactApplicationContext) : ReactContextBaseJava
|
|
|
32
24
|
options.getBoolean("autoTrackScreens")
|
|
33
25
|
} else false
|
|
34
26
|
|
|
35
|
-
val
|
|
36
|
-
options.
|
|
37
|
-
|
|
27
|
+
val environment = Environment.from(
|
|
28
|
+
if (options.hasKey("environment")) options.getString("environment") else null
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
val mockScreens: List<String>? = if (options.hasKey("mockScreens") && !options.isNull("mockScreens")) {
|
|
32
|
+
val array = options.getArray("mockScreens")
|
|
33
|
+
if (array != null) {
|
|
34
|
+
(0 until array.size()).map { array.getString(it) }
|
|
35
|
+
} else null
|
|
36
|
+
} else null
|
|
38
37
|
|
|
39
38
|
val strategy = if (options.hasKey("overlapStrategy")) {
|
|
40
39
|
OverlapStrategy.from(options.getString("overlapStrategy"))
|
|
@@ -48,8 +47,9 @@ class UXRateModule(reactContext: ReactApplicationContext) : ReactContextBaseJava
|
|
|
48
47
|
UXRate.configure(
|
|
49
48
|
application = application,
|
|
50
49
|
apiKey = apiKey,
|
|
50
|
+
environment = environment,
|
|
51
51
|
autoTrackScreens = autoTrack,
|
|
52
|
-
|
|
52
|
+
mockScreens = mockScreens,
|
|
53
53
|
overlapStrategy = strategy,
|
|
54
54
|
theme = theme
|
|
55
55
|
)
|
|
@@ -69,7 +69,6 @@ class UXRateModule(reactContext: ReactApplicationContext) : ReactContextBaseJava
|
|
|
69
69
|
val key = iterator.nextKey()
|
|
70
70
|
props[key] = properties.getString(key) ?: ""
|
|
71
71
|
}
|
|
72
|
-
|
|
73
72
|
UiThreadUtil.runOnUiThread {
|
|
74
73
|
UXRate.identify(userId, props)
|
|
75
74
|
promise.resolve(null)
|
|
@@ -24,16 +24,18 @@ All methods return `Promise<void>`.
|
|
|
24
24
|
```ts
|
|
25
25
|
interface ConfigureOptions {
|
|
26
26
|
apiKey: string;
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
environment?: 'production' | 'development' | 'local' | 'mock';
|
|
28
|
+
autoTrackScreens?: boolean;
|
|
29
|
+
mockScreens?: string[];
|
|
29
30
|
}
|
|
30
31
|
```
|
|
31
32
|
|
|
32
33
|
| Parameter | Type | Required | Description |
|
|
33
34
|
|-----------|------|----------|-------------|
|
|
34
35
|
| `apiKey` | `string` | Yes | Your UXRate API key. |
|
|
36
|
+
| `environment` | `string` | No | Backend environment: `'production'` (default), `'development'`, `'local'`, or `'mock'`. |
|
|
35
37
|
| `autoTrackScreens` | `boolean` | No | Enable native auto screen tracking. In React Native apps manual `setScreen` calls are preferred. |
|
|
36
|
-
| `
|
|
38
|
+
| `mockScreens` | `string[]` | No | Screen names for mock survey targeting. Only used when environment is `'mock'`. |
|
|
37
39
|
|
|
38
40
|
---
|
|
39
41
|
|
|
@@ -1,24 +1,19 @@
|
|
|
1
|
-
# Event Tracking
|
|
1
|
+
# Event Tracking — React Native
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> For concepts and best practices, see [Event Tracking](Event-Tracking).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Custom Events
|
|
6
6
|
|
|
7
7
|
```tsx
|
|
8
8
|
UXRate.track({ event: 'purchase_complete' });
|
|
9
9
|
UXRate.track({ event: 'onboarding_finished' });
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
dashboard to show a survey when a specific event fires.
|
|
12
|
+
## Screen Tracking
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
React Native runs inside a single native view, so auto-track sees only one screen. Report screens manually.
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
(Android), so the native auto-track feature sees only one screen. You should
|
|
19
|
-
report screens manually using `setScreen`.
|
|
20
|
-
|
|
21
|
-
### Per-screen tracking with `useFocusEffect`
|
|
16
|
+
### Per-screen with `useFocusEffect`
|
|
22
17
|
|
|
23
18
|
```tsx
|
|
24
19
|
import { useFocusEffect } from '@react-navigation/native';
|
|
@@ -33,13 +28,9 @@ function SettingsScreen() {
|
|
|
33
28
|
}
|
|
34
29
|
```
|
|
35
30
|
|
|
36
|
-
### Global
|
|
37
|
-
|
|
38
|
-
You can report every navigation change from a single place:
|
|
31
|
+
### Global with React Navigation
|
|
39
32
|
|
|
40
33
|
```tsx
|
|
41
|
-
import { NavigationContainer } from '@react-navigation/native';
|
|
42
|
-
|
|
43
34
|
<NavigationContainer
|
|
44
35
|
onStateChange={(state) => {
|
|
45
36
|
const route = state?.routes[state.index];
|
|
@@ -49,12 +40,3 @@ import { NavigationContainer } from '@react-navigation/native';
|
|
|
49
40
|
{/* screens */}
|
|
50
41
|
</NavigationContainer>
|
|
51
42
|
```
|
|
52
|
-
|
|
53
|
-
See the [React Navigation integration tutorial](../tutorials/react-navigation-integration.md) for a full walkthrough.
|
|
54
|
-
|
|
55
|
-
## Best practices
|
|
56
|
-
|
|
57
|
-
- Keep event names short and consistent (e.g. `snake_case`).
|
|
58
|
-
- Report screens as early as possible so survey targeting is accurate.
|
|
59
|
-
- Avoid tracking high-frequency events (e.g. scroll positions) -- they add
|
|
60
|
-
noise without improving targeting.
|
|
@@ -6,11 +6,19 @@ Get UXRate running in your React Native app in four steps.
|
|
|
6
6
|
|
|
7
7
|
Call `configure` once at app startup, typically in your root `App.tsx`:
|
|
8
8
|
|
|
9
|
+
**Quick test with mock surveys (no backend needed):**
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
UXRate.configure({ apiKey: 'YOUR_API_KEY', environment: 'mock' });
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Production:**
|
|
16
|
+
|
|
9
17
|
```tsx
|
|
10
18
|
import { UXRate } from 'react-native-uxrate';
|
|
11
19
|
|
|
12
20
|
useEffect(() => {
|
|
13
|
-
UXRate.configure({ apiKey: '
|
|
21
|
+
UXRate.configure({ apiKey: 'uxr_your_api_key' });
|
|
14
22
|
}, []);
|
|
15
23
|
```
|
|
16
24
|
|
|
@@ -1,33 +1,19 @@
|
|
|
1
|
-
# Session Replay
|
|
1
|
+
# Session Replay — React Native
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> For concepts, quality presets, and capture modes, see [Session Replay](Session-Replay).
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
The React Native module does not expose separate replay APIs -- replay capture
|
|
7
|
-
is started automatically by the native SDK when it is enabled for your project.
|
|
5
|
+
Replay is handled entirely by the native UXRate SDKs (iOS and Android). The React Native module does not expose separate replay APIs.
|
|
8
6
|
|
|
9
|
-
## Enabling
|
|
7
|
+
## Enabling Replay
|
|
10
8
|
|
|
11
9
|
1. Open the UXRate dashboard.
|
|
12
10
|
2. Navigate to your project settings.
|
|
13
11
|
3. Toggle **Session Replay** on.
|
|
14
|
-
4. Configure
|
|
12
|
+
4. Configure sampling rate and privacy masking.
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
without any additional code changes in your React Native app.
|
|
18
|
-
|
|
19
|
-
## Privacy masking
|
|
20
|
-
|
|
21
|
-
Sensitive views can be masked from replays. Masking rules are configured in
|
|
22
|
-
the UXRate dashboard and applied at the native layer. Because React Native
|
|
23
|
-
renders through native view hierarchies, the standard masking rules apply
|
|
24
|
-
to RN-rendered content as well.
|
|
14
|
+
No additional code changes are needed in your React Native app.
|
|
25
15
|
|
|
26
16
|
## Troubleshooting
|
|
27
17
|
|
|
28
|
-
- **Replay not appearing**:
|
|
29
|
-
|
|
30
|
-
- **Missing frames**: Replay capture runs at a reduced frame rate to minimise
|
|
31
|
-
performance impact. Short interactions may not produce visible frames.
|
|
32
|
-
- **Large payload warnings**: If your app has complex view hierarchies,
|
|
33
|
-
consider increasing the masking scope to reduce payload size.
|
|
18
|
+
- **Replay not appearing**: Check native SDK versions match minimum required for replay support.
|
|
19
|
+
- **Missing frames**: Replay runs at a reduced frame rate — short interactions may not produce visible frames.
|
package/example/App.tsx
CHANGED
|
@@ -13,14 +13,11 @@ const Stack = createNativeStackNavigator();
|
|
|
13
13
|
// ------------------------------------------------------------------
|
|
14
14
|
function App(): React.JSX.Element {
|
|
15
15
|
useEffect(() => {
|
|
16
|
+
// Mock environment — works immediately without dashboard setup.
|
|
17
|
+
// Switch to 'production' with your real API key for live surveys.
|
|
16
18
|
UXRate.configure({
|
|
17
19
|
apiKey: 'YOUR_API_KEY',
|
|
18
|
-
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
UXRate.identify({
|
|
22
|
-
userId: 'demo-user-1',
|
|
23
|
-
properties: { plan: 'trial' },
|
|
20
|
+
environment: 'mock',
|
|
24
21
|
});
|
|
25
22
|
}, []);
|
|
26
23
|
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -6,7 +6,6 @@ const LINKING_ERROR =
|
|
|
6
6
|
? `run \`pod install\` in your iOS project directory.\n`
|
|
7
7
|
: `rebuild your Android project.\n`);
|
|
8
8
|
|
|
9
|
-
// Throw a helpful error if the native module is not linked
|
|
10
9
|
const NativeUXRate = NativeModules.UXRate
|
|
11
10
|
? NativeModules.UXRate
|
|
12
11
|
: new Proxy(
|
|
@@ -18,73 +17,31 @@ const NativeUXRate = NativeModules.UXRate
|
|
|
18
17
|
}
|
|
19
18
|
);
|
|
20
19
|
|
|
21
|
-
/**
|
|
22
|
-
* React Native bridge for the UXRate SDK (iOS & Android).
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* // Minimal setup (App.js / App.tsx)
|
|
26
|
-
* import { UXRate } from 'react-native-uxrate';
|
|
27
|
-
*
|
|
28
|
-
* useEffect(() => {
|
|
29
|
-
* UXRate.configure({ apiKey: 'uxr_xxx' });
|
|
30
|
-
* }, []);
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* // Manual screen tracking
|
|
34
|
-
* useFocusEffect(() => {
|
|
35
|
-
* UXRate.setScreen('Home');
|
|
36
|
-
* });
|
|
37
|
-
*/
|
|
38
20
|
export const UXRate = {
|
|
39
21
|
/**
|
|
40
22
|
* Initialise the UXRate SDK. Call once at app startup.
|
|
41
23
|
*
|
|
42
24
|
* @param {string} apiKey - Your UXRate API key (required).
|
|
43
|
-
* @param {
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* @param {
|
|
25
|
+
* @param {string} [environment='production'] - Backend environment:
|
|
26
|
+
* 'production', 'development', 'local', or 'mock'.
|
|
27
|
+
* @param {boolean} [autoTrackScreens=false] - Auto-detect screens.
|
|
28
|
+
* @param {string[]} [mockScreens] - Screen names for mock survey targeting.
|
|
47
29
|
*/
|
|
48
|
-
configure({ apiKey,
|
|
30
|
+
configure({ apiKey, environment = 'production', autoTrackScreens = false, mockScreens }) {
|
|
49
31
|
if (Platform.OS !== 'ios' && Platform.OS !== 'android') return Promise.resolve();
|
|
50
|
-
return NativeUXRate.configure(apiKey, { autoTrackScreens,
|
|
32
|
+
return NativeUXRate.configure(apiKey, { environment, autoTrackScreens, mockScreens });
|
|
51
33
|
},
|
|
52
34
|
|
|
53
|
-
/**
|
|
54
|
-
* Identify the current user for segment-based survey targeting.
|
|
55
|
-
*
|
|
56
|
-
* @param {string} userId - A stable user identifier.
|
|
57
|
-
* @param {Object} [properties={}] - Optional key/value properties.
|
|
58
|
-
*/
|
|
59
35
|
identify({ userId, properties = {} }) {
|
|
60
36
|
if (Platform.OS !== 'ios' && Platform.OS !== 'android') return Promise.resolve();
|
|
61
37
|
return NativeUXRate.identify(userId, properties);
|
|
62
38
|
},
|
|
63
39
|
|
|
64
|
-
/**
|
|
65
|
-
* Track a custom event. Used for event-based trigger rules.
|
|
66
|
-
*
|
|
67
|
-
* @param {string} event - The event name.
|
|
68
|
-
*/
|
|
69
40
|
track({ event }) {
|
|
70
41
|
if (Platform.OS !== 'ios' && Platform.OS !== 'android') return Promise.resolve();
|
|
71
42
|
return NativeUXRate.track(event);
|
|
72
43
|
},
|
|
73
44
|
|
|
74
|
-
/**
|
|
75
|
-
* Report the current screen name. Call this on every navigation event.
|
|
76
|
-
*
|
|
77
|
-
* @param {string} name - The screen name to report.
|
|
78
|
-
*
|
|
79
|
-
* @example
|
|
80
|
-
* // With React Navigation
|
|
81
|
-
* <NavigationContainer
|
|
82
|
-
* onStateChange={(state) => {
|
|
83
|
-
* const route = state?.routes[state.index];
|
|
84
|
-
* if (route) UXRate.setScreen(route.name);
|
|
85
|
-
* }}
|
|
86
|
-
* >
|
|
87
|
-
*/
|
|
88
45
|
setScreen(name) {
|
|
89
46
|
if (Platform.OS !== 'ios' && Platform.OS !== 'android') return Promise.resolve();
|
|
90
47
|
return NativeUXRate.setScreen(name);
|
package/ios/UXRateModule.m
CHANGED
|
@@ -1,32 +1,67 @@
|
|
|
1
1
|
#import <React/RCTBridgeModule.h>
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
)
|
|
3
|
+
#if __has_include(<react_native_uxrate/react_native_uxrate-Swift.h>)
|
|
4
|
+
#import <react_native_uxrate/react_native_uxrate-Swift.h>
|
|
5
|
+
#else
|
|
6
|
+
#import "react_native_uxrate-Swift.h"
|
|
7
|
+
#endif
|
|
8
|
+
|
|
9
|
+
@interface UXRate : NSObject <RCTBridgeModule>
|
|
10
|
+
@end
|
|
11
|
+
|
|
12
|
+
@implementation UXRate
|
|
13
|
+
|
|
14
|
+
RCT_EXPORT_MODULE()
|
|
15
|
+
|
|
16
|
+
RCT_EXPORT_METHOD(configure:(NSString *)apiKey
|
|
17
|
+
options:(NSDictionary *)options
|
|
18
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
19
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
20
|
+
{
|
|
21
|
+
BOOL autoTrack = [options[@"autoTrackScreens"] boolValue];
|
|
22
|
+
NSString *environment = options[@"environment"];
|
|
23
|
+
NSArray<NSString *> *mockScreens = options[@"mockScreens"];
|
|
24
|
+
|
|
25
|
+
[UXRateBridge configure:apiKey
|
|
26
|
+
environment:environment
|
|
27
|
+
autoTrackScreens:autoTrack
|
|
28
|
+
mockScreens:mockScreens];
|
|
29
|
+
resolve(nil);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
RCT_EXPORT_METHOD(identify:(NSString *)userId
|
|
33
|
+
properties:(NSDictionary *)properties
|
|
34
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
35
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
36
|
+
{
|
|
37
|
+
NSMutableDictionary<NSString *, NSString *> *props = [NSMutableDictionary new];
|
|
38
|
+
[properties enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
|
|
39
|
+
if ([key isKindOfClass:[NSString class]] && [obj isKindOfClass:[NSString class]]) {
|
|
40
|
+
props[key] = obj;
|
|
41
|
+
}
|
|
42
|
+
}];
|
|
43
|
+
[UXRateBridge identify:userId properties:props];
|
|
44
|
+
resolve(nil);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
RCT_EXPORT_METHOD(track:(NSString *)event
|
|
48
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
49
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
50
|
+
{
|
|
51
|
+
[UXRateBridge track:event];
|
|
52
|
+
resolve(nil);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
RCT_EXPORT_METHOD(setScreen:(NSString *)name
|
|
56
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
57
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
58
|
+
{
|
|
59
|
+
[UXRateBridge setScreen:name];
|
|
60
|
+
resolve(nil);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
+ (BOOL)requiresMainQueueSetup {
|
|
64
|
+
return NO;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@end
|
package/ios/UXRateModule.swift
CHANGED
|
@@ -1,91 +1,55 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import UXRateSDK
|
|
3
3
|
|
|
4
|
-
///
|
|
5
|
-
///
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@objc(UXRate)
|
|
9
|
-
class UXRateModule: NSObject {
|
|
4
|
+
/// Implementation class for the React Native bridge.
|
|
5
|
+
/// Called from the Objective-C bridge in UXRateModule.m.
|
|
6
|
+
@objc(UXRateBridge)
|
|
7
|
+
public class UXRateBridge: NSObject {
|
|
10
8
|
|
|
11
|
-
/// Initialise the UXRate SDK.
|
|
12
|
-
///
|
|
13
|
-
/// - Parameters:
|
|
14
|
-
/// - apiKey: Your UXRate API key.
|
|
15
|
-
/// - options: Dictionary with optional keys:
|
|
16
|
-
/// - `autoTrackScreens` (Bool, default false)
|
|
17
|
-
/// - `useMockService` (Bool, default false)
|
|
18
9
|
@objc
|
|
19
|
-
func configure(
|
|
10
|
+
public static func configure(
|
|
20
11
|
_ apiKey: String,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
environment: String?,
|
|
13
|
+
autoTrackScreens: Bool,
|
|
14
|
+
mockScreens: [String]?
|
|
24
15
|
) {
|
|
25
|
-
let
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
16
|
+
let env: UXRateEnvironment = {
|
|
17
|
+
switch environment {
|
|
18
|
+
case "development": return .development
|
|
19
|
+
case "local": return .local
|
|
20
|
+
case "mock": return .mock
|
|
21
|
+
default: return .production
|
|
22
|
+
}
|
|
23
|
+
}()
|
|
29
24
|
|
|
30
25
|
DispatchQueue.main.async {
|
|
31
26
|
UXRate.configure(
|
|
32
27
|
apiKey: apiKey,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
theme: theme
|
|
28
|
+
environment: env,
|
|
29
|
+
autoTrackScreens: autoTrackScreens,
|
|
30
|
+
mockScreens: mockScreens
|
|
37
31
|
)
|
|
38
|
-
resolve(nil)
|
|
39
32
|
}
|
|
40
33
|
}
|
|
41
34
|
|
|
42
|
-
/// Identify the current user.
|
|
43
|
-
///
|
|
44
|
-
/// - Parameters:
|
|
45
|
-
/// - userId: Stable user identifier.
|
|
46
|
-
/// - properties: Optional `[String: String]` attributes.
|
|
47
35
|
@objc
|
|
48
|
-
func identify(
|
|
49
|
-
_ userId: String,
|
|
50
|
-
properties: NSDictionary,
|
|
51
|
-
resolve: @escaping RCTPromiseResolveBlock,
|
|
52
|
-
reject: @escaping RCTPromiseRejectBlock
|
|
53
|
-
) {
|
|
54
|
-
let props = properties as? [String: String] ?? [:]
|
|
36
|
+
public static func identify(_ userId: String, properties: [String: String]) {
|
|
55
37
|
DispatchQueue.main.async {
|
|
56
|
-
UXRate.identify(userId: userId, properties:
|
|
57
|
-
resolve(nil)
|
|
38
|
+
UXRate.identify(userId: userId, properties: properties)
|
|
58
39
|
}
|
|
59
40
|
}
|
|
60
41
|
|
|
61
|
-
/// Track a custom event.
|
|
62
42
|
@objc
|
|
63
|
-
func track(
|
|
64
|
-
_ event: String,
|
|
65
|
-
resolve: @escaping RCTPromiseResolveBlock,
|
|
66
|
-
reject: @escaping RCTPromiseRejectBlock
|
|
67
|
-
) {
|
|
43
|
+
public static func track(_ event: String) {
|
|
68
44
|
DispatchQueue.main.async {
|
|
69
45
|
UXRate.track(event: event)
|
|
70
|
-
resolve(nil)
|
|
71
46
|
}
|
|
72
47
|
}
|
|
73
48
|
|
|
74
|
-
/// Report the current screen name.
|
|
75
49
|
@objc
|
|
76
|
-
func setScreen(
|
|
77
|
-
_ name: String,
|
|
78
|
-
resolve: @escaping RCTPromiseResolveBlock,
|
|
79
|
-
reject: @escaping RCTPromiseRejectBlock
|
|
80
|
-
) {
|
|
50
|
+
public static func setScreen(_ name: String) {
|
|
81
51
|
DispatchQueue.main.async {
|
|
82
52
|
UXRate.setScreen(name)
|
|
83
|
-
resolve(nil)
|
|
84
53
|
}
|
|
85
54
|
}
|
|
86
|
-
|
|
87
|
-
/// React Native requires this to declare that the module does not have
|
|
88
|
-
/// a main queue setup requirement — methods are dispatched manually.
|
|
89
|
-
@objc
|
|
90
|
-
static func requiresMainQueueSetup() -> Bool { false }
|
|
91
55
|
}
|
package/package.json
CHANGED