1. How do I view a tracking solution?
Before burying points, it is necessary to determine where to track and which to track, that is, it is necessary to sort out the clear burial point requirements. In the Quick Tracking platform, explicit tracking requirements are called tracking solutions, and a specification template is designed for the tracking solution.

In the tracking plan, the required tracking contents include:
1. Event subject: Device ID and Account ID.
Device ID: The default device ID of a Windows device is a unique device ID at the application level. The device ID is automatically generated by the Quick Tracking SDK or you can call the setCustomDeviceId operation.
Account ID: the account ID of the client user to log on to the system. When a user logs on from different devices, the device ID changes, but the account ID does not change. For example, a user logs in separately using a computer and a pad.
2. User attribute: the attribute of account ID, such as the user whose account ID is "testdemo@111", "birthday" is "1999-02-13", and "membership level" is "platinum". The "birthday" and "membership" ratings are user attributes.
3. Global attributes: the attributes that are carried in each event after the global attribute is set once
4. Page browsing events: the events that are reported when the page is loaded. In the tracking plan, the events whose page code is the same as the event code are marked in blue.
5. Click, exposure, and custom events: the events that are reported when the client user interacts with the client.
2. Tracking notes
The input parameters do not support special strings such as single quotation marks and data types. Otherwise, events may fail to be dropped from the database and data may be lost.
The use of Chinese parameters requires that the source code file encoding is a valid Unicode(UTF-8 unsigned) encoding.
Except for the log switch operation, you must call the initQTPC operation before the operation takes effect.
In Windows 10. X, you can use GetVersionEx to obtain the system version inaccurately. In this case, you must add the manifest file to the project folder and add the manifest file to the project properties> inventory tools> input and output> additional inventory files. The following sample file is used:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> <asmv3:application> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <dpiAware>false</dpiAware> </asmv3:windowsSettings> </asmv3:application> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <!-- Windows 10 and Windows 11 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> <!-- Windows 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> <!-- Windows 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> <!-- Windows 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> <!-- Windows Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> </application> </compatibility> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <!-- UAC settings: - app should run at same integrity level as calling process - app does not need to manipulate windows belonging to higher-integrity-level processes --> <requestedExecutionLevel level="asInvoker" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo> </assembly>Limits on the input parameter size:
// If the keys and values of custom and global attributes exceed the upper limit, the settings cannot be completed.
const size_t kStringPropertyValueMaxLength=4096; // The upper limit of the custom property and global property value.
const size_t kStringPropertyKeyMaxLength=1024; // The maximum value of the custom property and global property key.
const size_t kStringArrayValueMaxSize=100; // The upper limit of the length of the custom attribute string array. If the upper limit is exceeded, the string array is truncated.
const size_t kStringMapValueMaxSize=50; // The upper limit of the global attribute set. If the upper limit is exceeded, no more data can be inserted.
const size_t kStringEventCodeMaxLength=500; // event code maximum length 3. Device ID, account ID, and user attribute settings
3.1 Device ID
The SDK supports custom device IDs. If you want to use custom device IDs, you must set the setCustomDeviceId interface to a valid value.
Interface functions:
// Specify the custom device ID.
QTFORPC_API QT_VOID setCustomDeviceId(QT_CSTR deviceId);Parameters:
Field | Feature | Full description | Required |
deviceId | const char * | The ID of the custom device. The value must be a non-empty string. | Yes |
string customDeviceId = "testId";
qtInterface->setCustomDeviceId(customDeviceId.c_str());3.2 Account ID
3.2.1 User Login
Quick Tracking SDK in the user statistics based on the device as the standard, if you need to count their own account, please use the following methods.
Interface functions:
// Log on to the application.
QTFORPC_API QT_VOID onProfileSignIn(QT_CSTR userID, QT_CSTR nick);Parameters:
Field | Feature | Full description | Required |
userID | const char * | User account ID, which is not an empty string | Yes |
nick | const char * | The nickname of the user. | No, no empty string can be passed |
qtInterface->onProfileSignIn("userId", "userNick");3.2.2 User Logout
If you no longer need to bind a user account, you can call the user logout method provided by the SDK. After you call the method, the SDK no longer sends user account-related content.
Interface functions:
// Log out.
QTFORPC_API QT_VOID onProfileSignOff();qtInterface->onProfileSignOff();3.3 user attribute upload
Use event encoding to $$_user_profile custom event upload. The event attributes carried by the event are stored in the user table as user attributes.
Note: The uploadUserProfile must be called after onPageStart and before onPageEnd to ensure data accuracy.
Interface functions:
// Upload user properties.
QTFORPC_API QT_VOID uploadUserProfile(QT_VSTR pageObj, QT_MAP customProperties);Parameters:
Field | Feature | Full description | Required |
pageObj | void * | We recommend that you use containers for WNDCLASS | Yes |
customProperties | const char * | The business parameter. You must specify the JSON literal template string for the parameter. | Yes |
WNDCLASS *wndClass = new WNDCLASS();
qtInterface->onPageStart(wndClass, "PageName");
std::string cusp = R"({
"age": 18,
"level": "King",
"name": "coolboy",
})";
qtInterface->uploadUserProfile(wndClass, cusp.c_str());
qtInterface->onPageEnd(wndClass);4. Global attributes
4.1 Register Global Attributes
Interface functions:
// Set global properties.
QTFORPC_API QT_VOID registerGlobalProperty(QT_CSTR key, QT_CSTR value);Parameters:
Field | Feature | Full description | Required |
key | const char * | Set the global property key | Yes |
value | const char * | Set the global property value | Yes |
qtInterface->registerGlobalProperty("key", "value");Note: If the key of an existing global attribute is the same as the key of an existing global attribute, the existing value is updated. If the key of an existing global attribute is different from the key of an existing global attribute, a new global attribute is inserted.
4.2 delete a global attribute
API functions:
// Delete global attributes based on the key.
QTFORPC_API QT_VOID unregisterGlobalProperty(QT_CSTR key);Parameters:
Field | Feature | Full description | Required |
key | const char * | Global attribute key to delete | Yes |
qtInterface->unregisterGlobalProperty("key");4.3 to obtain a single global attribute based on a key
API functions:
// Obtain global properties based on the key.
QTFORPC_API QT_VOID getGlobalProperty(QT_CSTR key, QT_STR value, QT_INT size);Parameters:
Field | Feature | Full description | Required |
key | const char * | The key of the global property to get | Yes |
value | char * | The global property value to get | Yes |
size | int | Global attribute value length | Yes |
// The size is set as required.
char value[64] = { 0 };
qtInterface->getGlobalProperty("key", value, 64);
string myValue = value;4.4 Get All Global Properties
API functions:
// Obtain all global attributes.
QTFORPC_API QT_VOID getGlobalProperties(QT_STR properties, QT_INT size);Parameters:
Field | Feature | Full description | Required |
properties | char * | The tracking of global properties to get | Yes |
size | int | Global attribute value length | Yes |
// The size is set as required.
char properties[128] = { 0 };
qtInterface->getGlobalProperties(properties);
std::map<string, string> myProperties = QT::Helper::QT_DeserializePerson(properties, 128);Note: The obtained properties need to be converted into std::map through QT::Helper::QT_DeserializePerson interface.
5. Page browsing events
Manual tracking on the 5.1 page
Note
onPageStart is used by the SDK to record page entry information. onPageStart does not report events. PageView events are reported only when onPageEnd is called.
The onPageStart and onPageEnd methods must be used in pairs. The pageObj values must be the same. If the onPageEnd method does not exist or is inconsistent with the pageObj values that are used by onPageStart, the information recorded by onPageStart does not take effect. This affects the accuracy of page event tracking.
Interface functions:
// The page starts to be displayed.
QTFORPC_API QT_VOID onPageStart(QT_VSTR pageObj, QT_CSTR pageName);
// The page starts to disappear.
QTFORPC_API QT_VOID onPageEnd(QT_VSTR pageObj);Parameters:
Field | Feature | Full description | Required |
pageObj | void * | We recommend that you use the container object WNDCLASS. In the same page, when you call onPageEnd, you need to pass the same pageObj as onPageStart. | Yes |
pageName | const char * | Event code of page events | Yes |
WNDCLASS *wndClass = new WNDCLASS();
qtInterface->onPageStart(wndClass, "PageName");
qtInterface->onPageEnd(wndClass);5.2 setting page event properties
API functions:
// Set the page event parameters.
QTFORPC_API QT_VOID updatePageProperties(QT_VSTR pageObj, QT_MAP pageProperties);Parameters:
Field | Feature | Full description | Required |
pageObj | void * | We recommend that you use the container object WNDCLASS. In the same page, when calling updatePageProperties, you need to pass the same pageObj as onPageStart. | Yes |
pageProperties | const char * | page parameter, which corresponds to the event attribute in the page event log. You must specify the JSON literal template string for the parameter. | Yes |
WNDCLASS *wndClass = new WNDCLASS();
qtInterface->onPageStart(wndClass, "PageName");
std::string cusp = R"({
"param_str": "hello c++",
"param_num": 1900,
"param_bool": true,
"param_list": ["hello", "world", "c++"]
})";
qtInterface->updatePageProperties(wndClass, cusp.c_str());
qtInterface->onPageEnd(wndClass);5.3 Container Skip
Skips the previous page (the source page is the container page) of the current page (the child page in the container).
API functions:
// Skip a container for multi-container nesting.
QTFORPC_API QT_VOID skipPage(QT_VSTR pageObj);Field | Feature | Full description | Required |
pageObj | void * | We recommend that you use the container object WNDCLASS. In the same page, when calling skipPage, you need to pass the same pageObj as onPageStart. | Yes |
WNDCLASS *wndClass = new WNDCLASS();
qtInterface->onPageStart(wndClass, "firstPage");
std::string cusp = R"({
"param_str": "hello c++",
"param_num": 1900,
"param_bool": true,
"param_list": ["hello", "world", "c++"]
})";
qtInterface->updatePageProperties(wndClass, cusp.c_str());
qtInterface->onPageEnd(wndClass);
WNDCLASS *wndClass1 = new WNDCLASS();
qtInterface->onPageStart(wndClass1, "secondPage");
qtInterface->onPageEnd(wndClass1);
WNDCLASS *wndClass2 = new WNDCLASS();
// Skips the previous page of thirdPage, that is, secondPage. In this case, the ref_page_name of thirdPage is firstPage. If skipPage is not called, the ref_page_name is secondPage.
qtInterface->skipPage(wndClass2);
qtInterface->onPageStart(wndClass2, "thirdPage");
qtInterface->onPageEnd(wndClass2);6. Event tracking
Custom events can be used to track user behavior and record the specific details of the behavior.
Note: To use trackEvent or trackEventWithPageName, ensure that the call is made after onPageStart and before onPageEnd to ensure data accuracy.
Interface functions:
// The tracking event.
QTFORPC_API QT_VOID trackEvent(QT_VSTR pageObj, QT_CSTR id, QT_MAP customProperties);
// The tracking event includes the page name.
QTFORPC_API QT_VOID trackEventWithPageName(QT_VSTR pageObj, QT_CSTR id, QT_MAP customProperties, QT_CSTR pageName);Parameters:
Field | Feature | Full description | Required |
pageObj | void * | We recommend that you use the container object WNDCLASS. When calling trackEvent or trackEventWithPageName on the same page, you need to pass the same pageObj as onPageStart. | Yes |
id | const char * | Event encoding. You cannot pass a parameter that starts with "$$_" as a non-empty string of id | Yes |
customProperties | const char * | The event attribute. You must specify the JSON literal template string for the parameter. | No |
pageName | const char * | Page encoding | No |
WNDCLASS *wndClass = new WNDCLASS();
qtInterface->onPageStart(wndClass, "PageName");
std::string cusp = R"({
"param_str": "hello c++",
"param_num": 1900,
"param_bool": true,
"param_list": ["hello", "world", "c++"]
})";
qtInterface->trackEventWithPageName(wndClass, "test_event", cusp.c_str(), "PageName");
qtInterface->onPageEnd(wndClass);7. Manually track application startup and exit events
Note: The use of enterForeground/enterForegroundWithPageName or enterBackground/enterBackgroundWithPageName requires that the onPageStart and and onPageEnd are called before the call to ensure data accuracy.
Interface functions:
// Enter the foreground.
QTFORPC_API QT_VOID enterForeground(QT_VSTR pageObj, QT_MAP customProperties);
// Enter the foreground with a PageName.
QTFORPC_API QT_VOID enterForegroundWithPageName(QT_VSTR pageObj, QT_MAP customProperties, QT_CSTR pageName);
// Enter the background.
QTFORPC_API QT_VOID enterBackground(QT_VSTR pageObj, QT_MAP customProperties);
// Enter the background with the PageName.
QTFORPC_API QT_VOID enterBackgroundWithPageName(QT_VSTR pageObj, QT_MAP customProperties, QT_CSTR pageName);Parameters:
Field | Feature | Full description | Required |
pageObj | void * | We recommend that you use the container object WNDCLASS. When calling trackEvent or trackEventWithPageName on the same page, you need to pass the same pageObj as onPageStart. | Yes |
customProperties | const char * | The business parameter. You must specify the JSON literal template string for the parameter. | No |
pageName | const char * | Page encoding | No |
WNDCLASS *wndClassForeground = new WNDCLASS();
qtInterface->onPageStart(wndClassForeground, "StartPageName");
std::string start_cusp = R"({
"param_str": "hello c++",
"param_num": 1900,
"param_bool": true,
"param_list": ["hello", "world", "c++"]
})";
qtInterface->enterForeground(wndClassForeground, start_cusp.c_str());
qtInterface->onPageEnd(wndClassForeground);
WNDCLASS *wndClassBackground = new WNDCLASS();
qtInterface->onPageStart(wndClassBackground, "EndPageName");
std::string end_cusp = R"({
"param_str": "hello c++",
"param_num": 1900,
"param_bool": true,
"param_list": ["hello", "world", "c++"]
})";
qtInterface->enterBackground(wndClassBackground, end_cusp.c_str());
qtInterface->onPageEnd(wndClassBackground);8. Other
8.1 stop saving data to local
You can call finiQTPC to stop data dropping from a database. Currently, only the Stop method is available.
API functions:
// deinitialize QT
QTFORPC_API QT_VOID finiQTPC(QT_CB cb);Parameters:
Field | Feature | Full description | Required |
cb | void | Lifecycle hooks | Yes |
void callBackFunc()
{
fprintf(stderr, "finiQTPC callback\n");
}
qtInterface->finiQTPC(callBackFunc);Real-time debugging mode 8.2
Call turnOnRealTimeDebug to enable the real-time debugging mode. The data reporting interval becomes 30 seconds. Call turnOffRealTimeDebug to disable real-time debugging.
Note: Before the application is officially launched, disable the real-time debugging mode of the SDK.
API functions:
// Enable the real-time debugging mode.
QTFORPC_API QT_VOID turnOnRealTimeDebug(QT_MAP configs);
// Disable real-time debugging.
QTFORPC_API QT_VOID turnOffRealTimeDebug();Parameters:
Field | Feature | Full description | Required |
configs | const char * | Configure parameters. The input parameters must be in the form of a map tracking. Then, call QT::Helper::QT_Serializable serialization. | Yes |
map<string, string> configs;
configs["debug_key"] = "test";
std::string sconfig;
QT::Helper::QT_Serializable(sconfig, configs);
qtInterface->turnOnRealTimeDebug(sconfig.c_str());
qtInterface->turnOnRealTimeDebug();Enable the quick upload mode 8.3
Call setFastUploadMode to enable the fast upload mode. The data reporting interval changes to one report per second. The default value is three reports per second.
Note: Before the application is officially launched, disable the SDK quick upload mode.
API functions:
// Enable the quick upload mode.
QTFORPC_API QT_VOID setFastUploadMode();qtInterface->setFastUploadMode();