React Native SDK

Updated at:

SDK information

SDK name

Version

SHA-512

Package name

QuickTracking React Native SDK

Latest version: 2.1.4

Changelog: React Native SDK Changelog

amwUB7FOgHkJwZt0WD9tDZt1GWoNZzKWDh/yCcnCyv8gc0RvmlsxaOIUOh3DGFBGfsqYmdN7uNW9vHVAfo4ujw==

react-native-quicktracking-analytics-module

Integration overview

The Quick Tracking React Native SDK is an extension of the native Quick Tracking client-side SDK. It wraps common tracking APIs, such as those for global properties, page properties, and custom events. You must integrate and configure the SDK separately for the React Native, Android, and iOS platforms.

React Native SDK integration

NPM Package URL: react-native-quicktracking-analytics-module

Install the npm package

# npm
npm install react-native-quicktracking-analytics-module

# yarn
yarn add react-native-quicktracking-analytics-module

# pnpm
pnpm add react-native-quicktracking-analytics-module

Import the SDK

import * as QT from "react-native-quicktracking-analytics-module";

Obtain the AppKey and tracking domain

Go to the console

Log in to the Quick Tracking console and click Management console.

image

Integrate your application

Find the application where you want to set up tracking. Go to the application list, select the desired organization, and in the Actions column, click Details or Integrate.

image

Android base configuration

Configure the Maven repository

In your project's root build.gradle file, add the SDK's Maven repository URL to both the buildscript and allprojects blocks.

buildscript {
    repositories {
    google()
    jcenter()
    maven { url 'https://repo1.maven.org/maven2/' }
  }
  dependencies {
      classpath 'com.android.tools.build:gradle:3.4.0'}
      // NOTE: Do not place your application dependencies here; they belong
      // in the individual module build.gradle files
  }
}
allprojects {
    repositories {
    google()
    jcenter()
    maven { url 'https://repo1.maven.org/maven2/' }
  }
}

Add dependencies

In your app-level build.gradle file (usually app/build.gradle), add the required dependency to the dependencies block.

dependencies {
    implementation fileTree(include:['*.jar'], dir:'libs')

    //QuickTracking Analytics SDK
    implementation 'com.lydaas.qtsdk:qt-px-common:1.8.6.PX'
}

Important: If you have already added the QuickTracking React Native SDK dependency through package.json, you do not need to integrate the native QuickTracking Android SDK separately.

Configure tracking validation

In your AndroidManifest.xml file, locate the <activity> tag for your MainActivity and add the following code block. Replace appkey in android:scheme with your own AppKey.

// 1. The URL scheme defaults to "atm.YOUR_APPKEY" and cannot be changed.
// 2. Use a separate intent-filter, placed at the same level as other intent-filters.
// Do not add the following code inside another intent-filter.

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="atm.appkey" />
</intent-filter>

Configure permissions

The analytics SDK requires the host app to grant the following permissions:

Permission

Purpose

ACCESS_NETWORK_STATE

Detects the network connection type to avoid sending data during network outages, which conserves data and power.

READ_PHONE_STATE (Optional)

Obtains the device's IMEI to uniquely identify the user for analytics services.

ACCESS_WIFI_STATE

Obtains the Wi-Fi MAC address, which serves as a unique identifier on devices without an IMEI (e.g., tablets, TV boxes).

INTERNET

Allows the application to connect to the internet and send analytics data.

The following is an example of the AndroidManifest.xml manifest file:

<manifest ……> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <application ……>
</manifest>

Obfuscation configuration

If you use a code obfuscation tool like ProGuard, add the following rules to exclude the Quick Tracking SDK from obfuscation. This is required for the SDK to function correctly.

-keep class com.umeng.** {*;}
-keep class org.repackage.** {*;}

-keep class com.quick.qt.** {*;}
-keep class rpk.quick.qt.** {*;}

-keepclassmembers class * {
   public <init> (org.json.JSONObject);
}
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

The SDK uses reflection to access resource files by referencing the R.java file. Obfuscation tools like ProGuard might remove R.java. If you encounter this issue, add the following configuration:

-keep public class [YOUR_PACKAGE_NAME].R$*{
    public stac final int 

iOS base configuration

Integrate with CocoaPods

Navigate to your iOS project directory and run the following command:

cd ios && pod install   

Configure tracking validation

Add your URL scheme to your project. In Xcode, navigate to your target's Info tab and find the URL Types section.

Set the URL scheme to atm.yourappkey.

image.png

Option 1: In AppDelegate, call the [QTMobClick handleUrl:url] function to handle the URL.

- (BOOL)application:(UIApplication *)application openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
    if ([QTMobClick handleUrl:url]) {
        return YES;
    }
    return YES;
}

Option 2: Use the Linking module in React Native to listen for app wake-up callbacks and call QT.handleUrl(url) to handle the URL.

import { Linking } from 'react-native';

  // 1. Listen for the 'url' event (when the app is already running and is opened by a URL)
  React.useEffect(() => {
    const handleOpenURL = (event: { url: string }) => {
      QT.handleUrl(event.url);
    };
    // Add the listener
    const subscription = Linking.addEventListener('url', handleOpenURL);
    // Clean up the listener
    return () => {
      subscription.remove();
    };
  }, []);
  // 2. Handle the initial URL on app cold start (when the app is not running and is launched by a URL)
  React.useEffect(() => {
    Linking.getInitialURL().then((url) => {
      if (url) {
        QT.handleUrl(url);
      }
    });
  }, []);

For more details on tracking validation, see the Tracking validation guide.

Tracking API

Enable SDK analytics (initialization)

Initializing the SDK enables analytics. Place the initialization method in App.tsx to ensure it executes as early as possible.

Example
import * as QT from 'react-native-quicktracking-analytics-module';
import { Platform } from 'react-native';

// Place initialization-related code here
QT.setTrackDomain(
  'YOUR_TRACKING_DOMAIN',
  'YOUR_BACKUP_TRACKING_DOMAIN' // Can be an empty string
);
if (Platform.OS === 'android') {
  QT.init('YOUR_APPKEY', 'YOUR_CHANNEL_NAME');
} else {
  QT.init('YOUR_APPKEY', 'App Store');
}

export default function App() {
  return (
    ...
  );
}

Set the tracking domain

Before initializing the SDK, you must call the setTrackDomain method to set your tracking domain.

function setTrackDomain(mainTrackDomain: string, subTrackDomain: string): void;

Parameter

Description

mainTrackDomain

The primary tracking domain.

subTrackDomain

The backup tracking domain.

Example

import * as QT from "react-native-quicktracking-analytics-module";

QT.setTrackDomain(
  'YOUR_TRACKING_DOMAIN',
  'YOUR_BACKUP_TRACKING_DOMAIN' // Pass an empty string '' if you do not have one.
);

Pre-initialization

The preInit method is required for Android only.

function preInit(appKey: string, channel: string): void;

Parameter

Description

appKey

The unique application key provided by the QT console.

channel

The download channel.

Example

You must call preInit in your native Android Application class to prevent tracking issues, such as missed events.

class MainApplication : Application(), ReactApplication {

  private var appKey = "YOUR_APPKEY"
  private var domain = "YOUR_TRACKING_DOMAIN"
  override fun onCreate() {
    super.onCreate()
    QtConfigure.setCustomDomain(domain, domain) // Set the tracking domain
    // QtConfigure.setLogEnabled(true) // Enable logging
    QtConfigure.preInit(
      this,
      appKey,
      "YOUR_CHANNEL_NAME"
    )
   // loadReactNative(this)
  }
}

Formal initialization

You must call this method to initialize the SDK. Call this method only after the user has consented to your privacy policy.

function init(appKey: string, channel: string): void

Parameter

Description

appKey

The unique application key provided by the QT console.

channel

The download channel.

Example

import * as QT from "react-native-quicktracking-analytics-module";

QT.init('YOUR_APPKEY', 'quicktracking');

Enable logging

function enableLog(enable: boolean): void;

Parameter

Description

enable

true to enable logging, false to disable.

Example

import * as QT from "react-native-quicktracking-analytics-module";

QT.enableLog(true);

User account reporting

User sign-in

This value corresponds to "Signed-in Users" in the product. The number of signed-in users is calculated by counting the unique IDs uploaded via this API.

function profileSignIn(ID: string, provider?: string): void

Parameter

Description

ID

The user account ID, which must be less than 64 bytes. This value is used to calculate the number of unique signed-in users.

provider

This field is deprecated. Pass null or an empty string.

Example

import * as QT from "react-native-quicktracking-analytics-module";

QT.profileSignIn('USER_ID');

User sign-out

Call this method when a user signs out. After this call, the SDK stops sending account-related information.

function profileSignOff(): void

Example

import * as QT from "react-native-quicktracking-analytics-module";

QT.profileSignOff();

Upload user properties

To upload user properties, send a custom event with the event ID $$_user_profile. The parameters of this event are then treated as the user's properties.

function sendEvent(eventId: string, params: any): void

Parameter

Description

eventId

The ID of the event to track. Use $$_user_profile for user properties.

params

An object of key-value pairs that describe the event parameters.

Important: You must upload user properties after reporting the user account sign-in.

Example:

import * as QT from "react-native-quicktracking-analytics-module";

QT.profileSignIn("John Doe");

const user = {
  gender: "male",
  age: "8"
}
QT.sendEvent("$$_user_profile", user);

The example above sets the properties for "John Doe" to: gender: male, age: 8.

Global properties

Global properties are attributes that are included with every event.

Register a global property

function registerGlobalProperty(globalProperty: any): void

Parameter

Description

globalProperty

An object of key-value pairs representing the global properties. This must be a flat object; nested objects are not supported.

Note:

  1. Property names and string-type property values can only contain letters, numbers, and underscores.

  2. On Android, JavaScript boolean values are not supported for property values. Convert them to 0 or 1 in your JavaScript code.

  3. On Android, properties with null or undefined values are filtered out by the native SDK. If you need to analyze null values, define a custom default empty value (e.g., an empty string '').

  4. On iOS, property values do not support null or undefined. You must filter them out manually before passing them to the SDK.

Example:

import * as QT from "react-native-quicktracking-analytics-module";

QT.registerGlobalProperty({
    name: 'MyApp',
    description: 'this_is_an_app',
    aBoolean: 1, // Convert boolean values to 0 or 1
    aNull: '', // Convert null or undefined to an empty string
    // For properties that might be null or undefined, 
    // you must define a custom default value.
    aNumber: 66, 
});

Unregister a global property

function unregisterGlobalProperty(propertyName: string): void

Parameter

Description

propertyName

The name of the global property to unregister.

Example:

import * as QT from "react-native-quicktracking-analytics-module";

QT.unregisterGlobalProperty('name'); // Unregisters the 'name' global property

Get a global property

async function getGlobalProperty(propertyName: string): Promise<any>

Parameter

Description

propertyName

The name of the global property to get.

Example:

import * as QT from "react-native-quicktracking-analytics-module";

const nameValue = await QT.getGlobalProperty('name');
console.log('getGlobalProperty call successful', nameValue);

Get all global properties

async function getGlobalProperties(): Promise<any>

Example:

import * as QT from "react-native-quicktracking-analytics-module";

const globalProperties = await QT.getGlobalProperties();
console.log('getGlobalProperties call successful', globalProperties);

Clear all global properties

function clearGlobalProperties(): void

Example:

import * as QT from "react-native-quicktracking-analytics-module";

QT.clearGlobalProperties(); // Warning: This removes all global properties. Use with caution.

Track page view events

To collect and analyze page paths and time spent on pages, you can manually track page view events using the following API calls.

function onPageStart(pageName: string): void
function onPageEnd(pageName: string): void

Parameter

Description

pageName

The page identifier.

Example:

import * as QT from "react-native-quicktracking-analytics-module";

QT.onPageStart('MainPage');
QT.onPageEnd('MainPage');

Important:

onPageStart records the entry into a page but does not send an event. The page view event is only sent when onPageEnd is called.

You must call onPageStart and onPageEnd in pairs with the same pageName. If a call to onPageEnd is missing or has a mismatched pageName, the SDK will not record the page view.

Upload page properties

You can attach page properties to the current page.

function uploadPageProperties(pageName: string, params: EventParams): void

Parameters:

Parameter

Description

pageName

The page identifier of the target page. This must match the pageName of the current page view (the last page started with onPageStart that has not yet ended); otherwise, the call has no effect.

params

An object of key-value pairs that describe the page parameters. The object must be a flat structure and does not support nested objects.

Example:

import * as QT from "react-native-quicktracking-analytics-module";

QT.uploadPageProperties('detail_page', { test: 1 });

Note:

  1. This function must be called between onPageStart and onPageEnd.

  2. Property names and string-type property values can only contain letters, numbers, and underscores.

  3. On Android, JavaScript boolean values are not supported for property values. Convert them to 0 or 1 in your JavaScript code.

  4. On Android, properties with null or undefined values are filtered out by the native SDK. If you need to analyze null values, define a custom default empty value (e.g., an empty string '').

  5. On iOS, property values do not support null or undefined. You must filter them out manually before passing them to the SDK.

Track custom events

You can use custom events to track specific user behaviors and record details about those actions.

Use the sendEvent function to track events:

function sendEvent(eventId: string, params?: any, pageName?: string): void

Parameter

Description

eventId

The identifier for the event being tracked.

params

An object of key-value pairs that describe the event parameters. The object must be a flat structure and does not support nested objects.

pageName

The page identifier where the event occurred.

Example:

import * as QT from "react-native-quicktracking-analytics-module";

// Custom event with parameters
QT.sendEvent(
  'event1',
  {
    name: 'quick_tracking',
    method: 'func',
  }
);

// Custom event with parameters and a page identifier
QT.sendEvent(
  'event2',
  {
    name: 'quick_tracking',
    method: 'func',
  },
  'main-page'
);

Note:

  • Events with multiple parameters can fulfill the analysis needs of calculation and counter events.

  • For calculation-type events, different parameter types correspond to different calculation methods, which can be broadly divided into numeric and string types.

    • Numeric types support sum, max, min, average, and unique count calculations.

    • String types support unique count calculations.

Important:

Similar to global properties, event properties have different type handling requirements on Android and iOS:

  1. On Android, JavaScript boolean values are not supported. Convert them to 0 or 1 in your JavaScript code.

  2. On Android, properties with null or undefined values are filtered out by the native SDK. If you need to analyze null values, define a custom default empty value.

  3. On iOS, property values do not support null or undefined. You must filter them out manually.

Track bridge events

Bridge events are used in scenarios where H5 content is bridged to React Native. Use this function to send H5 logs to the native app.

function sendEventForH5(data: string): void

Parameter

Description

data

The log body of the event forwarded from the H5 page.

Example:

import * as QT from "react-native-quicktracking-analytics-module";

const content = data.nativeEvent.data;
QT.sendEventForH5(content);

Embed H5 pages

Integrate the Web SDK

For this step, see the Web SDK documentation.

Forward H5 logs to React Native

<script charset="UTF-8">
  ...
  // SDK integration and configuration
  ...
  
  // Forward custom page events (clicks, element exposures, etc.)
  aplus_queue.push({
    action: 'aplus.aplus_pubsub.subscribe',
    arguments: ['mw_change_hjlj', function (content) {
      var eventData = content && content.what_to_send && content.what_to_send.hjljdataToUmNative;
      if (/* Check for iOS environment */) {
        window.ReactNativeWebView.postMessage(JSON.stringify(eventData), '*'); 
      } else {
        window.ReactNativeWebView.postMessage(JSON.stringify(eventData));
      }
    }]
  })
  
  aplus_queue.push({
    action: 'aplus.aplus_pubsub.subscribe',
    arguments: ['mw_change_pv', function (content) {
      var pvData = content && content.what_to_send && content.what_to_send.pvdataToUmNative;
      if (/* Check for iOS environment */) {
        window.ReactNativeWebView.postMessage(JSON.stringify(pvData), '*');    
      } else {
        window.ReactNativeWebView.postMessage(JSON.stringify(pvData));
      }
    }]
  })
</script>

Report logs from WebView

import * as React from 'react'
import { WebView } from 'react-native-webview';
import { QT } from 'react-native-quicktracking-analytics-module';
import { Platform, SafeAreaView } from 'react-native';

export default function WebPage() {
  const onMessage = (data) => {
    try {
      const content = data.nativeEvent.data;
      QT.sendEventForH5(content);
    } catch (error) {
      console.log('webview message error:', error);
    }
  };
  
  return (
    <SafeAreaView style={{ flex: 1 }}>
    	<WebView
      	...
        onMessage={onMessage}
      	...
      />
    </SafeAreaView>
  );
}

Other APIs

Disable the SDK

const disableSDK: () => void;

Example

import * as QT from "react-native-quicktracking-analytics-module";

QT.disableSDK();

Enable the SDK

const enableSDK: () => void;

Example

import * as QT from "react-native-quicktracking-analytics-module";

QT.enableSDK();

Set a custom device ID

const setCustomDeviceId: (deviceId: string) => void;

Parameter

Description

deviceId

The custom device ID.

Example

import * as QT from "react-native-quicktracking-analytics-module";

QT.setCustomDeviceId('YOUR_CUSTOM_DEVICE_ID');

Get the device ID

const getDeviceId: () => Promise<any>;

Example

import * as QT from "react-native-quicktracking-analytics-module";

const deviceID = await QT.getDeviceId(); 
console.log('getDeviceId call successful', JSON.stringify(deviceID)); 

React Native auto-tracking

Requires QuickTracking React Native SDK version 2.0.0 or later.

Automatic page view collection

The SDK supports automatic page view event collection by integrating with the popular React Navigation library. The following is an example:

import {QT} from 'react-native-quicktracking-analytics-module';
import {
  NavigationContainer,
  useNavigationContainerRef,
} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();

const App = () => {
  const navigationRef = useNavigationContainerRef();
  const routeNameRef = useRef('');

  return (
    <NavigationContainer
      ref={navigationRef}
      onReady={() => {
        const currentRouteName = navigationRef.getCurrentRoute()?.name;
        routeNameRef.current = currentRouteName;
        // Set page identifier
        QT.onPageStart(currentRouteName);
      }}
      onStateChange={() => {
        const previousRouteName = routeNameRef.current;
        const currentRouteName = navigationRef.getCurrentRoute()?.name;

        if (previousRouteName !== currentRouteName) {
          // Set page properties as needed (optional)
          QT.uploadPageProperties(previousRouteName, {
            test_page_p_1: 1,
            test_page_p_2: "test"
          });
          // Collect page view event
          QT.onPageEnd(previousRouteName);
          if (currentRouteName) {
            // Update to the new page identifier
            QT.onPageStart(currentRouteName);
            routeNameRef.current = currentRouteName;
          }
        }
      }}
    >
      ...
    </NavigationContainer>
  )
}

Automatic click collection

In your project's root directory, run the following Node.js command:

node node_modules/react-native-quicktracking-analytics-module/src/hook.js -run

Note: To restore the original files, you can run the reset command:

node node_modules/react-native-quicktracking-analytics-module/src/hook.js -reset

Disable auto-tracking for controls

To support hybrid development scenarios, you can disable automatic control-click event collection for React Native controls. Add the QTSDKConfig configuration to your project's package.json file:

{
  "name": "reactnative_demo",
  "QTSDKConfig": {
    "enableAutoCLK": true
  }
}

The enableAutoCLK field has the following values:

  • true: Enables auto-tracking for React Native controls.

  • false: Disables auto-tracking for React Native controls.

Note: To enable automatic collection for React Native control-click events, you must also run the Node.js command mentioned above.

Enable auto-tracking for iOS

#import <QTCommon/UMConfigure.h>
#import <QTCommon/MobClick.h>
#import <UMCommonLog/UMCommonLogHeaders.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    // Enable auto-tracking for native control clicks
    [QTMobClick setAutoEventEnabled:YES];
    
    return YES;
}

Enable auto-tracking for Android

import com.quick.qt.analytics.QtTrackAgent;

public class MainApplication extends Application implements ReactApplication {
  ...
    
  @Override
  public void onCreate() {
    super.onCreate();
    ...
    // Enable auto-tracking for native control clicks
    QtTrackAgent.setAutoEventEnabled(true);
    ...
  }

  ...
}

Set custom properties for controls

Note: This is supported only for React Native controls such as TouchableHighlight, TouchableOpacity, Pressable, and TouchableWithoutFeedback.

<Pressable
  onPress={()=>{}}
  qtParams={{
    pressable: "press_1",
  }}
>
  {({pressed}) => (
    <Text style={styles.text}>
      {pressed ? 'Pressed!' : 'Pressable Control'}
    </Text>
  )}
</Pressable>

<TouchableHighlight 
  onPress={()=>{}} 
  qtParams={{aTouchableHighlight: 1, b: 2}}>
  <Text>TouchableHighlight Control</Text>
</TouchableHighlight>

<TouchableOpacity 
  onPress={()=>{}} 
  qtParams={{aTouchableOpacity: 1, b: 2}}>
  <Text>TouchableOpacity Control</Text>
</TouchableOpacity>

<TouchableWithoutFeedback 
  onPress={()=>{}} 
  qtParams={{aTouchableWithoutFeedback: 1, b: 2}}>
  <Text>TouchableWithoutFeedback Control</Text>
</TouchableWithoutFeedback>

Ignore a single control

Set the ignore field to true in the event properties.

<TouchableHighlight 
  onPress={()=>{}} 
  qtParams={{
    aTouchableHighlight: 1, 
    b: 2,
    ignore: true
  }}>
  <Text>TouchableHighlight Control</Text>
</TouchableHighlight>

Troubleshooting: Embedded HTML data not received on Android

Ensure the required network permissions are configured in your AndroidManifest.xml file.

References

QuickTracking Android SDK Integration Guide

QuickTracking iOS SDK Integration Guide

React Native Android Native Modules

React Native iOS Native Modules

License

MIT

Made with create-react-native-library