参考 iOS 集成 说明。
注:SDK 初始化需要参考上述文档在原生中完成
iOS 端创建一个类.h 中引入<React/RCTBridgeModule.h>,遵守 RCTBridgeModule 协议
例:
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
@interface HMTRNAgent : NSObject<RCTBridgeModule>
@end
在.m 的实现中提供发送接口,在接口中调用 HMTSDK 的原生方法
#import "HMTRNAgent.h"
#import "HMTAgentSDK.h"
@implementation HMTRNAgent
RCT_EXPORT_MODULE();
//自定义事件
RCT_EXPORT_METHOD(sendAction:(NSString *)name params:(NSDictionary *)param)
{
//RN与原生端交互是在子线程,而SDK会在方法中获取一些页面信息,这些信息必须在主线程获取,故需要先回到主线程再调用对应方法
dispatch_async(dispatch_get_main_queue(), ^{
[HMTAgentSDK postAction:name acc:1 property:param];
});
}
//自定义持续事件开始
RCT_EXPORT_METHOD(sendActionStart:(NSString *)name actionSign:(NSString *)sign)
{
dispatch_async(dispatch_get_main_queue(), ^{
[HMTAgentSDK postActionStart:name uactSing:sign];
});
}
//自定义持续事件结束
RCT_EXPORT_METHOD(sendActionEnd:(NSString *)name actionSign:(NSString *)sign params:(NSDictionary *)param)
{
dispatch_async(dispatch_get_main_queue(), ^{
[HMTAgentSDK psotActionEnd:name uactSign:sign property:param callback:nil];
});
}
//页面开始
RCT_EXPORT_METHOD(sendActivityStart:(NSString *)pageName)
{
dispatch_async(dispatch_get_main_queue(), ^{
[HMTAgentSDK startTracPage:pageName];
});
}
//页面结束
RCT_EXPORT_METHOD(sendActivityEnd:(NSDictionary *)param)
{
dispatch_async(dispatch_get_main_queue(), ^{
[HMTAgentSDK endTracPage:param];
});
}
//绑定账户ID
RCT_EXPORT_METHOD(identify:(NSString *)accountID)
{
dispatch_async(dispatch_get_main_queue(), ^{
[HMTAgentSDK bindAccountId:accountID];
});
}
@end
在 Javascript 中 调用处引入 NativeModules 模块
import { NativeModules } from "react-native";
const HMTRNAgent = NativeModules.HMTRNAgent;
通过 HMTRNAgent 对象,调用在预定义的方法;
触发携带属性的行为时,如登录行为,并附带用户名和会员等级两个属性:
HMTRNAgent.sendAction("login", {
username: "value1",
memberlevel: "value2"
});
触发不带属性的行为时,例如收藏,如下:
HMTRNAgent.sendAction("like", {});
触发页面的进入和离开时,比如调用 RN 中的页面进入和离开,从而监测一个商品详情页:
//页面进入时
HMTRNAgent.sendActivityStart("detail_page");
//页面离开时,并且携带页面属性
HMTRNAgent.sendActivityEnd("detail_page", { good_id: "123" });
//若页面离开,不带页面属性
HMTRNAgent.sendActivityEnd("detail_page", {});
用户登陆后,调用绑定用户 ID 方法,使登录期内的日志都携带该 ID
HMTRNAgent.identify("123456");
触发一个持续性的事件,如记录用户按住某按钮的时间:
//用户按下时,第二个参数为事件唯一ID,一对事件中需要一致
HMTRNAgent.sendActionStart("holdon", "xsddf");
//用户释放按钮,同时传入属性,如这次按下获得的奖励值
HMTRNAgent.sendActionStart("holdon", "xsddf", { reward: "12" });
//用户释放按钮,不包含额外属性
HMTRNAgent.sendActionStart("holdon", "xsddf", {});
参考 Android SDK 集成 说明
SDK 的初始化代码需要在 MainApplication 类中的 onCreate() 回调中被调用,如下:
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
HMTAgent.Initialize(this, 1);
}
首先, 复制 HMTModule 模块到 RN-Android 项目中, 找到 ..\app\src\main\java\YOUR_PKG_NAME
目录, 在该目录中创建 HMTModule.java
文件,并将如下内容复制到 HMTModule.java
文件中 HMTModule 代码如下:
public class HMTModule extends ReactContextBaseJavaModule {
public HMTModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "HMTRNAgent";
}
@Nullable
@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
return constants;
}
// 触发普通事件
@ReactMethod
public void sendAction(String actionName, ReadableMap map) {
HashMap<String, Object> hashMap = getHashMap(map);
if (hashMap == null || hashMap.isEmpty()) {
HMTAgent.onAction(getReactApplicationContext(), actionName);
} else {
HParams params = new HParams();
params.setParams(hashMap);
HMTAgent.onAction(getReactApplicationContext(), actionName, params);
}
}
//触发持续事件-开始
@ReactMethod
public void sendActionStart(String actionName) {
HMTAgent.onActionStart(getReactApplicationContext(), actionName);
}
//触发持续事件-结束
@ReactMethod
public void sendActionEnd(String actionName, ReadableMap map) {
HashMap<String, Object> hashMap = getHashMap(map);
if (hashMap == null || hashMap.isEmpty()) {
HMTAgent.onActionEnd(getReactApplicationContext(), actionName);
} else {
HParams params = new HParams();
params.setParams(hashMap);
HMTAgent.onActionEnd(getReactApplicationContext(), actionName, params, "-1");
}
}
@android.support.annotation.Nullable
private HashMap<String, Object> getHashMap(ReadableMap map) {
HashMap<String, Object> hashMap = null;
if (null != map) {
hashMap = map.toHashMap();
}
return hashMap;
}
//触发页面-开始
@ReactMethod
public void sendActivityStart(String pageName) {
HMTAgent.onResume(getReactApplicationContext(), pageName);
}
//触发页面-结束
@ReactMethod
public void sendActivityEnd(String pageName, ReadableMap map) {
HashMap<String, Object> hashMap = getHashMap(map);
if (hashMap == null || hashMap.isEmpty()) {
HMTAgent.onPause(getReactApplicationContext(), pageName);
} else {
HParams params = new HParams();
params.setParams(hashMap);
HMTAgent.onPause(getReactApplicationContext(), params, null, pageName);
}
}
//绑定AccountID
@ReactMethod
public void identify(String accountID) {
HMTAgent.bindAccountID(getReactApplicationContext(), accountID);
}
}
然后,复制注册模块文件到 RN-Android 项目中, 找到 ..\app\src\main\java\YOUR_PKG_NAME
目录,在该目录中创建 HMTRNPackage.java
文件,并将如下内容复制到 HMTRNPackage.java
文件中
HMTRNPackage 代码如下:
public class HMTRNPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new HMTModule(reactContext));
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
这个 HMTRNPackage
类 需要在 MainApplication.java
类中的 getPackages()
方法中被提供。 示例代码如下:
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new HMTRNPackage()
);
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
在 Javascript 中 调用处引入 NativeModules 模块
import { NativeModules } from "react-native";
const HMTRNAgent = NativeModules.HMTRNAgent;
通过 HMTRNAgent 对象,调用在预定义的方法;
触发携带属性的行为时,如登录行为,并附带用户名和会员等级两个属性:
HMTRNAgent.sendAction("login", {
username: "value1",
memberlevel: "value2"
});
触发不带属性的行为时,例如收藏,如下:
HMTRNAgent.sendAction("like", {});
触发页面的进入和离开时,比如调用 RN 中的页面进入和离开,从而监测一个商品详情页:
//页面进入时
HMTRNAgent.sendActivityStart("detail_page");
//页面离开时,并且携带页面属性
HMTRNAgent.sendActivityEnd("detail_page", { good_id: "123" });
//若页面离开,不带页面属性
HMTRNAgent.sendActivityEnd("detail_page", {});
用户登陆后,调用绑定用户 ID 方法,使登录期内的日志都携带该 ID
HMTRNAgent.identify("123456");
触发一个持续性的事件,如记录用户按住某按钮的时间:
//用户按下时,第二个参数为事件唯一ID,一对事件中需要一致
HMTRNAgent.sendActionStart("holdon", "xsddf");
//用户释放按钮,同时传入属性,如这次按下获得的奖励值
HMTRNAgent.sendActionStart("holdon", "xsddf", { reward: "12" });
//用户释放按钮,不包含额外属性
HMTRNAgent.sendActionStart("holdon", "xsddf", {});
Flutter sdk 的集成需要俩个步骤
注:SDK 初始化需要参考上述文档在原生中完成
参考HYPERS FLUTTER INSTALLING TAB 文档进行集成
触发携带属性的行为时,如登录行为,并附带用户名和会员等级两个属性:
HypersAnalytics.sendAction("login", actionCount: 1, actionParams: {"username": "value1","memberlevel":"value2"});
触发不带属性的行为时,例如收藏,如下:
HypersAnalytics.sendAction("like");
触发页面的进入和离开时,比如调用 Flutter 中的页面进入和离开,从而监测一个商品详情页:
// 页面进入时
HypersAnalytics.sendActivityStart("detail_page");
// 页面离开时,并且携带页面属性
HypersAnalytics.sendActivityEnd("detail_page", activityParams: {"good_id": "value1"});
// 页面离开时,并且不需要携带页面属性
HypersAnalytics.sendActivityEnd("detail_page");
用户登陆后,调用绑定用户 ID 方法,使登录期内的日志都携带该 ID:
HypersAnalytics.identify("123456");
APP/小程序中的 WebView 与 Web JS SDK 快速集成的方案,可以直接查看这篇文章: App 与小程序内嵌页面方案
。 如果您想自定义控制,请查阅以下说明。
针对有些 App 需要对内嵌页面中的行为进行跟踪,由 android / iOS 注入 javascript 对应的方法 , 在 HTML 中可以进行调用,并传入对应需要跟踪的参数。
首先需要集成 iOS SDK 或者 Android SDK。
在 Android Native 端添加如下代码:
在加载 webview 之前添加:
HMTAgent.setWebViewAction(WebView webview, Context context);
注:此处 Context 必须为 activity 对象。
在 iOS Native 端添加如下代码:
UIWebView 场景:
Naive 端只需在 UIWebView 加载完成的代理方法中调用 SDK 提供的对应方法即可:
- (void)webViewDidFinishLoad:(UIWebView *)webView{
[HMTAgentSDK setActionOnWebView:webView];
}
WKWebView 场景:
Navie 端需要在 WKWebView 初始化完成后调用 SDK 提供给 WkWebView 的设置方法
[HMTAgentSDK setActionOnWKWebView:self.WKWebView];
并且需要在页面销毁时调用 SDK 提供的注销网页方法
[HMTAgentSDK removeHmtWKWebAction:self.WKWebView];
在页面的 head 中添加基础代码,用于判断当前平台类型,从而分别调用 iOS 和 Android 的方法:
var tracker = {
postData: function (handle, data) {
var message = JSON.stringify(data);
if (window.webkit) {
window.webkit.messageHandlers[handle].postMessage(message);
} else if (window.hmt) {
window.hmt[handle](message);
} else if (window[handle]) {
window[handle](message);
} else {
console.error(handle + " 方法不存在,请检查是否安装了 SDK");
}
},
sendAction: function (params) {
this.postData("hmtAction", params);
},
sendActionStart: function (params) {
this.postData("hmtActionStart", params);
},
sendActionEnd: function (params) {
this.postData("hmtActionEnd", params);
},
sendActivityStart: function (params) {
this.postData("hmtActivityStart", params);
},
sendActivityEnd: function (params) {
this.postData("hmtActivityEnd", params);
},
identify: function (accountID) {
this.postData("hmtBindAccountID", { accountID: accountID });
},
};
在页面上调用方法,以下方法不区分 iOS/Android,通过基础代码判断平台,再分别调用两个平台的方法:
以事件的调用为例,在页面上触发自定义事件,使用:
tracker.sendAction({
act_name: "register",
activity: "user_info_page",
age: "24",
act_count: 3,
level: "golden",
});
对于页面的跟踪,进行成对调用:
// H5在页面进入时调用
tracker.sendActivityStart({
activity: "user_info_page",
});
//在H5页面离开时调用
tracker.sendActivityEnd({
activity: "user_info_page",
user_type: "member",
});
其中 activity 为自定义的页面名称,一个页面的 start 和 end 时名称都为必填且需一致,在 end 时可添加自定义属性参数。
若用户登录或注册发生在 H5 页面中,可调用绑定 accountid 接口:
tracker.identify("member1321232");
对于持续事件的跟踪,进行成对调用:
// 事件开始时
tracker.sendActionStart({
act_name: "playmusic",
activity: "user_info_page",
UACT: "a123456",
});
// 事件结束时
tracker.sendActionEnd({
act_name: "playmusic",
UACT: "a123456",
activity: "user_info_page",
musicname: "Imagine",
});