第二步:集成 热力引擎 SDK ReactNative模块
对于 React Native 开发的应用,推荐使用 npm 或 yarn 方式集成热力引擎 SDK ReactNative 模块,在您项目的根目录下执行以下命令: ( 请在您项目的根目录执行下述命令, 且命令完成后, 记得需要在原生项目里更新对远程库的依赖)
如果您创建的产品数据存储区域是中国大陆
//使用npm
npm install solarengine-analysis-react-native-cn
//使用yarn
yarn add solarengine-analysis-react-native-cn
如果您创建的产品数据存储区域是非中国大陆
//使用npm
npm install solarengine-analysis-react-native
//使用yarn
yarn add solarengine-analysis-react-native
注意:React Native 0.60 及以上版本会 autolinking,不需要执行下边的 react-native link 命令。
react-native link solarengine-analysis-react-native
若需要使用指定版本的原生SDK
(示例为海外版; 国内版本请将路径中的solarengine-analysis-react-native 改为solarengine-analysis-react-native-cn)
//未指定platform时,同时修改iOS & Android 的SDK版本
node node_modules/solarengine-analysis-react-native/cli.js set-config --sdkVersion=1.3.1.0
//指定修改iOS SDK版本
node node_modules/solarengine-analysis-react-native/cli.js set-config --sdkVersion=1.3.1.2 --platform=ios
//指定修改Android SDK的版本
node node_modules/solarengine-analysis-react-native/cli.js set-config --sdkVersion=1.3.1.4 --platform=android
Android 配置
在您项目根目录的build.gradle添加 maven 仓库配置,具体配置如下:
maven {
url "https://maven-android.solar-engine.com/repository/se_sdk_for_android/"
}
maven {
url "https://developer.huawei.com/repo/"
}
maven {
url "https://developer.hihonor.com/repo"
}
Android
在项目 AndroidManifest.xml 文件中,加入如下权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
注:android.permission.READ_PHONE_STATE 为非必要权限。如果开发者使用了数据存储区域是中国大陆的 SDK,热力引擎 SDK 并不会要求开发者强制获取此权限。如果开发者获取了此权限且 Android 系统在 6.0 以上,需要动态申请此权限。
iOS
支持Xcode版本:14.0或更高
适用范围:适用于 iOS 11.0 及以上的操作系统。
HarmonyOS
参考文档 集成 SolarEngine HarmonyOS SDK:SolarEngine 快速集成文档
SolarEngine React Native 插件 v1.7.1 及以上,支持 HarmonyOS 埋点
集成 SolarEngine React Native 插件的 HarmonyOS 实现
将组件 solarengine-analysis-react-native-cn 中 harmony 目录下 cpp 和 ets 下的 solarengine 文件夹

分别拖拽到 RN 生成的鸿蒙项目中 src/main/cpp 和 src/main/ets 目录中

配置修改
1. 在 CMakeLists.txt 中添加新增的胶水代码
在 entry/src/main/cpp/CMakeLists.txt 中定义 cpp 的 solarengine 路径,并添加到编译构建中:
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(RNOH_CPP_DIR "${OH_MODULE_DIR}/@rnoh/react-native-openharmony/src/main/cpp")
set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
add_compile_definitions(WITH_HITRACE_SYSTRACE)
set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
add_subdirectory("${RNOH_CPP_DIR}" ./rn)
add_library(rnoh_app SHARED
"./PackageProvider.cpp"
"${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
"./solarengine/SolarengineAnalysisReactNative.cpp" # 手动添加
)
target_link_libraries(rnoh_app PUBLIC rnoh)
2. 在 entry/src/main/cpp/PackageProvider.cpp 中创建 cpp 侧的 package 对象:SolarEnginePackage
#include "RNOH/PackageProvider.h"
#include "solarengine/SolarEnginePackage.h" // 手动添加
using namespace rnoh;
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {
std::make_shared<SolarEnginePackage>(ctx) // 手动添加
};
}
3. 在 entry/src/main/ets/RNPackagesFactory.ets 中添加创建 SolarEnginePackage 的方法
import { RNPackageContext, RNPackage } from '@rnoh/react-native-openharmony/ts';
import { SolarEnginePackage } from './solarengine/SolarEnginePackage'; // 手动添加
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [
new SolarEnginePackage(ctx) // 手动添加
];
}
Example
Example in Github
第四步:预初始化
在应用安装后首次冷启动时,需要先预初始化 SDK,预初始化时 SDK 不采集任何个人信息也不会向热力引擎上报数据
方法示例
调用示例
import SolarEngine from 'solarengine-analysis-react-native'; //如果您创建的产品数据存储区域不是中国大陆
//import SolarEngine from 'solarengine-analysis-react-native-cn'; //如果您创建的产品数据存储区域是中国大陆
let appKey = "";
if (Platform.OS === 'ios') {
appKey = "your_iOS_appkey";// 替换为您为iOS App申请的appkey
} else if (Platform.OS === 'android') {
appKey = "your_Android_appkey";// 替换为您为Android App申请的appkey
}
SolarEngine.preInit(appKey);
第五步:初始化配置(可选)
se_initial_config参数说明
本配置类用于初始化 SDK 时,对服务能力与数据采集行为进行精细化控制,分为核心功能开关、辅助功能开关、数据采集开关三类参数。
此方法返回的 config 配置作为可选参数,如未设置则为默认值
import SolarEngine from 'solarengine-analysis-react-native';
let config = {};
config.enableLog = true;
一、核心功能开关配置
控制 SDK 核心业务能力的启用 / 停用,直接决定归因、分析等核心服务是否生效。注:关闭相关核心功能开关将影响数据上报链路,您将无法在热力引擎后台正常使用该模块的全部功能。
| 方法名 |
参数类型 |
是否必填 |
说明 |
示例 |
| enableAttribution |
boolean |
否 |
是否开启归因服务,默认开启。关闭后将停用全部归因相关能力,无法获取归因结果、延迟deeplink、deeplink等相关服务;若同时关闭分析服务,SDK 将停止上报所有数据。 |
config.enableAttribution = true; |
| enableAnalytics |
boolean |
否 |
是否开启分析服务,默认开启。关闭后 A/B 测试、在线参数等所有分析类功能均无法使用;若同时关闭归因服务,SDK 将不再上报任何数据。 |
config.enableAnalytics = true;
|
二、辅助功能开关
控制 SDK 的运行模式、调试日志、网络策略、授权等待、辅助功能(如延迟 Deeplink)等非核心业务的运行行为。
| 方法名 |
参数类型 |
是否必填 |
说明 |
示例 |
| enableLog |
boolean |
否 |
是否开启本地调试日志,默认为 false,不开启。 |
config.enableLog = true; |
| enableDebug |
boolean |
否 |
是否开启 Debug 模式,默认不开启。 |
config.enableDebug = true; |
| enable2G |
boolean |
否 |
是否在 2G 网络时上报事件,默认为 false,不上报。 |
config.enable2G = true; |
| enableGDPR |
boolean |
否 |
是否设置为 GDPR 区域。欧盟运营需符合 GDPR,用户拒绝采集敏感信息时设 true,默认采集。 |
config.enableGDPR = true; |
| enableCoppa |
boolean |
否 |
是否支持《儿童在线隐私权保护法》(COPPA)。符合 COPPA 规定时设 true |
config.enableCoppa = true; |
| enableKidsApp |
boolean |
否 |
是否标记为儿童应用 (Kids App)。定向儿童应用时设 true |
config.enableKidsApp = true; |
| enableDeferredDeeplink |
boolean |
否 |
是否启用延迟 deeplink 功能,默认为 false,不开启。 |
config.enableDeferredDeeplink = true; |
| enableSeparatedAttribution |
boolean |
否 |
是否开启新版归因功能,获取归因结果更快 |
config.enableSeparatedAttribution = true; |
| ios.attAuthorizationWaitingInterval |
number |
否 |
ATT 授权等待秒数(最多 120 秒),用于首次上报事件。 |
config.ios.attAuthorizationWaitingInterval = 30; |
| android.metaAppId |
string |
否 |
海外 Meta 归因所需 Meta AppID。 |
config.android.metaAppId = 'your_meta_appid'; |
| android.enablePersonalizedAd |
boolean |
否 |
欧盟 Google 投放时,传入用户是否允许 Google 将其数据用于个性化广告的意见结果。 |
config.android.enablePersonalizedAd = true; |
| android.enableUserData |
boolean |
否 |
欧盟 Google 投放时,传入用户是否同意将其数据发送到 Google 的意见结果。 |
config.android.enableUserData = true; |
| android.supportMultiProcess |
boolean |
否 |
是否启用多进程支持(v1.2.9.4+),默认 false。 |
config.android.supportMultiProcess = true; |
| harmony.authorizationTimeout |
number |
否 |
等待用户授权结果的最大时长,单位为毫秒,默认使用 SDK 内部等待时长。 |
config.harmony.authorizationTimeout = 120; |
三、数据采集开关
控制ipv6、OAID、UA等参数等数据是否采集。注:关闭对应数据采集参数后,将会影响归因、分析模块的数据能力,您将无法在热力引擎后台正常使用相关功能
| 方法名 |
参数类型 |
是否必填 |
说明 |
示例 |
| enableIPV6 |
boolean |
否 |
是否采集ipv6地址, 不采集设置为false,默认 true(采集) |
config.enableIPV6=true; |
| enableLanguage |
boolean |
否 |
是否采集设备语言, 不采集设置为false,默认 true(采集) |
config.enableLanguage=true; |
| enableLocale |
boolean |
否 |
是否采集设备所在地区, 不采集设置为false,默认 true(采集) |
config.enableLocale=true; |
| enableTimeZone |
boolean |
否 |
是否采集设备所在时区, 不采集设置为false,默认 true(采集) |
config.enableTimeZone=true; |
| enableScreenWH |
boolean |
否 |
是否采集屏幕宽度/屏幕高度, 不采集设置为false,默认 true(采集) |
config.enableScreenWH=true; |
| enableDensity |
boolean |
否 |
是否采集屏幕密度, 不采集设置为false,默认 true(采集) |
config.enableDensity=true; |
| enableNetworkType |
boolean |
否 |
是否采集网络状态, 不采集设置为false,默认 true(采集) |
config.enableNetworkType=true; |
| enableUA |
boolean |
否 |
是否采集UA, 不采集设置为false,默认 true(采集) |
config.enableUA=true; |
| enableOAID |
boolean |
否 |
是否采集OAID, 不采集设置为false,默认 true(采集) |
config.enableOAID=true; |
| harmony.enableODID |
boolean |
否 |
是否采集ODID, 不采集设置为false,默认 true(采集) |
config.harmony.enableODID=true; |
| harmony.enableAAID |
boolean |
否 |
是否采集AAID, 不采集设置为false,默认 true(采集) |
config.harmony.enableAAID=true; |
| android.isImeiEnabled |
boolean |
否 |
是否允许采集 IMEI ,不采集配置为 false |
config.android.isImeiEnabled=true; |
| android.isAndroidIDEnabled |
boolean |
否 |
是否允许采集 AndroidID ,不采集配置为 false |
config.android.isAndroidIDEnabled=true; |
第六步:初始化
方法示例
export function initialize(appKey:string,options:SolarEngineInitiateOptions,completion: (result: InitiateCompletionInfo) => void)
参数说明
| 参数名 |
参数含义 |
参数类型 |
是否必传 |
| appKey |
第一步获取的 appkey |
string |
是 |
| options |
SDK 配置项 |
SolarEngineInitiateOptions
|
是 |
|
|
初始化回调函数 |
|
是 |
SolarEngineInitiateOptions 说明
| 属性名 |
属性含义 |
属性类型 |
是否必传 |
| config |
SDK相关相关的配置信息 |
se_initial_config |
否 |
| remoteConfig |
"在线参数和A/B 测试模块" 相关的配置信息 |
RemoteConfig |
否 |
| attribution |
接收归因信息的回调函数 |
attribution |
否 |
| deeplink |
接收deeplink信息的回调函数 |
deeplink |
否 |
|
|
接收延迟deeplink信息的回调函数 |
|
否 |
RemoteConfig 说明
| 参数名称 |
参数含义 |
参数类型 |
是否必传 |
| enabled |
是否启用在线参数SDK,默认为关闭状态 |
boolean |
是 |
| mergeType |
SDK配置合并策略,默认情况下服务端配置跟本地缓存配置合并,具体释义参考下方参数解释,可选字段 |
RemoteConfigMergeType |
否 |
| customIDProperties |
自定义ID,跟用户在后台设置的使用自定义ID匹配对应 |
Object |
否 |
| customIDEventProperties |
自定义ID事件属性值,跟用户在后台设置的使用自定义ID事件属性值匹配对应 |
Object |
否 |
| customIDUserProperties |
自定义ID用户属性值,跟用户在后台设置的使用自定义ID用户属性值匹配对应 |
Object |
否 |
RemoteConfigMergeType (参数合并策略) 介绍
| 参数名称 |
参数含义 |
|
User
|
app首次启动或版本更新时, 使用服务端配置跟用户默认配置合并,此方法可以清除本地缓存配置 |
| Cache |
使用服务端配置跟用户本地已有缓存配置合并,在线参数SDK默认合并策略 |
接收归因信息的回调函数
type attribution = (code:number,attribution?:Object) => void;
接收deeplink信息的回调函数
type deeplink = (code:number,deepLinkInfo?:DeepLinkInfo) => void;
| 参数名称 |
参数含义 |
参数类型 |
|
sedpLink
|
跳转参数 |
string |
| turlId |
7位短链 |
string |
| from |
链接类型 |
string |
| customParams |
自定义参数 |
Object |
接收延迟deeplink信息的回调函数
type deferredDeeplink = (code:number,deferredDeepLinkInfo?:DeferredDeepLinkInfo) => void;
| 参数名称 |
参数含义 |
参数类型 |
|
sedpLink
|
跳转参数 |
string |
| turlId |
7位短链 |
string |
| sedpUrlscheme |
用户在创建deeplink链接时填写的 |
string |
调用示例
async function Initiate(){
log("Initiate" );
let appKey = "";
if (Platform.OS === 'ios') {
appKey = "your_iOS_appKey";
} else if (Platform.OS === 'android') {
appKey = "your_Android_appKey";
}
let config:se_initial_config = buildInitialConfig();
let remoteConfig:RemoteConfig = buildRemoteConfig();
let attribution:attribution = buildAttribution();
let deeplink:deeplink = buildDeeplinkResponse();
let deferredDeeplink:deferredDeeplink = buildDeferredDeeplinkResponse();
let initiateOptions:SolarEngineInitiateOptions = {
config:config,
remoteConfig:remoteConfig,
attribution:attribution,
deeplink:deeplink,
deferredDeeplink:deferredDeeplink
}
SolarEngine.initialize(appKey,initiateOptions,(result:InitiateCompletionInfo) => {
if (result.success) {
Alert.alert('SolarEngine SDK Initiate Complete!')
}
});
}
SDK相关相关的配置信息
function buildInitialConfig():se_initial_config{
let config:se_initial_config = {
enableLog: true,
enableDebug: false,
...
};
return config;
}
"在线参数和A/B 测试模块" 相关的配置信息
function buildRemoteConfig():RemoteConfig{
let remoteConfig:RemoteConfig = {
enabled:true,
mergeType:RemoteConfigMergeType.Cache,
customIDProperties:{"name":"name_value"},
customIDEventProperties:{"age":28},
customIDUserProperties:{"key":"value"},
}
return remoteConfig;
}
接收归因信息的回调函数
function buildAttribution():attribution{
const handleAttribution:attribution = (code:number,attributionInfo?:Object) => {
console.log("attribution code: " + code);
if (code === 0){
console.log("attributionInfo: " + JSON.stringify(attributionInfo));
const typedValue = attributionInfo as {channel_name : string,
attribution_time:string,
re_data: object};
console.log("channel_name: " + typedValue.channel_name)
console.log("attribution_time: " + typedValue.attribution_time)
const re_dataValue = typedValue.re_data as {install_time:string,
report_time:string
}
if(typedValue.re_data != null){
console.log("re_data.install_time: " + re_dataValue.install_time)
console.log("re_data.report_time: " + re_dataValue.report_time)
}else{
console.log("re_data: is null" )
}
}
}
return handleAttribution;
}
接收deeplink信息的回调函数
function buildDeeplinkResponse():deeplink{
const handleDeepLink: deeplink = (code:number,deepLinkInfo?: DeepLinkInfo) => {
if(code === 0){
if(deepLinkInfo){
console.log("deepLinkInfo.sedpLink: " + deepLinkInfo.sedpLink);
}
}else{
console.log("code: " + code);
}
};
return handleDeepLink;
}
接收延迟deeplink信息的回调函数
function buildDeferredDeeplinkResponse(): deferredDeeplink {
const handleDeferredDeeplink: deferredDeeplink = (
code: number,
deferreddeeplink?: DeferredDeepLinkInfo
) => {
if (code === 0) {
if (deferreddeeplink) {
log('deferreddeeplink.sedpLink: ' + deferreddeeplink.sedpLink);
}
} else {
log('code: ' + code);
}
};
return handleDeferredDeeplink;
}
初始化回调 InitiateCompletionInfo errorCode 码:
| 101 |
SDK未预初始化 |
| 102 |
appkey非法 |
| 103 |
context为null(仅Android生效) |
| 104 |
distinct_id生成失败(仅Android生效) |
第七步:获取归因回调信息
SDK提供获取归因结果信息接口,开发者可使用归因信息做埋点等逻辑处理
SDK提供两种方式获取归因结果信息
- 设置归因结果回调:当SDK获取归因结果成功或者失败时会给出回调(此接口为异步回调)
- 直接获取归因结果:直接从SDK缓存中获取归因结果,SDK还没归因结果时直接返回null(此接口为同步返回)
7.1 SDK提供两种方式获取归因结果信息
「新版」通过回调获取归因结果(推荐)
调用示例
SolarEngine.initialize(
APP_KEY,
{
config: {
enableSeparatedAttribution: true,
},
uaAttribution: (code, data) => {
if (code === 0) {
console.log('UA 归因成功:', data);
} else {
console.log('UA 归因失败:', code);
}
},
reAttribution: (code, data) => {
if (code === 0) {
console.log('RE 归因成功:', data);
} else {
console.log('RE 归因失败:', code);
}
},
},
result => {
console.log('初始化结果:', result);
}
);
重要提示:使用回调模式接收归因结果时,归因监听器必须在 initialize 初始化阶段完成配置之前。若初始化之后再设置监听器,会导致归因结果获取不准确,可参考上方代码示例。
「新版」直接获取归因结果(推荐)
除了在初始化时添加归因回调,也可业务后续主动调用 API 读取归因结果。
直接获取归因结果的方法返回的是本地缓存,如果本地缓存还未生成,那么归因结果将会为 {}
调用示例
//获取拉新归因结果
const uaAttribution = SolarEngine.getUAAttributionData();
//获取拉活归因结果
const reAttribution = SolarEngine.getREAttributionData();
「旧版」回调获取归因结果(即将下线)
设置归因结果回调
function buildAttribution():attribution{
const handleAttribution:attribution = (code:number,attributionInfo?:Object) => {
console.log("attribution code: " + code);
if (code === 0){
console.log("attributionInfo: " + JSON.stringify(attributionInfo));
const typedValue = attributionInfo as {channel_name : string,
attribution_time:string,
re_data: object};
console.log("channel_name: " + typedValue.channel_name)
console.log("attribution_time: " + typedValue.attribution_time)
const re_dataValue = typedValue.re_data as {install_time:string,
report_time:string
}
if(typedValue.re_data != null){
console.log("re_data.install_time: " + re_dataValue.install_time)
console.log("re_data.report_time: " + re_dataValue.report_time)
}else{
console.log("re_data: is null" )
}
}
}
return handleAttribution;
}
方法示例:
export function retrieveAttribution(): Object|null;
调用示例:
function retrieveAttribution(){
let attribution:Object|null = SolarEngine.retrieveAttribution();
if (attribution != null) {
log('attribution: ' + JSON.stringify(attribution));
const object = attribution as { channel_name: string; attribution_time: string};
log("channel_name:" + object.channel_name);
log("attribution_time:" + object.attribution_time);
}else{
log("attribution is null");
}
}