概述
此页面是云眼SDK的使用参考。
以下内容将指导安装云眼SDK以及在代码中运行优化方案。 可以通过右上角的按钮来切换及查看其他语言的使用参考。
使用示例
SDK在代码中运行优化方案的基本用法请参考右侧的代码。
首先,需要根据云眼应用的数据文件来进行Eyeofcloud对象的初始化。
首先激活优化方案,然后进行分流,最后追踪目标事件的转化。注意,只有在 activate
已经被调用的情况下,才可进行分流,以及调用track
函数用于跟踪一个或多个试验的目标事件的转化
请注意,SDK要求调用activate
和 track
方法时提供唯一用户ID 。
Example Code
from eyeofcloud import eyeofcloud # Initialize an Eyeofcloud client eyeofcloud_client = eyeofcloud.Eyeofcloud(datafile) # Activate user in an experiment variation = eyeofcloud_client.activate('my_experiment', user_id) if variation == 'control': # Execute code for variation A elif variation == 'treatment': # Execute code for variation B else: # Execute default code # Track conversion event eyeofcloud_client.track('my_conversion', user_id)
Example Code
import com.eyeofcloud.ab.Eyeofcloud; // Initialize an Eyeofcloud client eyeofcloudClient = Eyeofcloud.builder(datafile, myEventHandler).build(); // Activate user in an experiment Variation variation = eyeofcloudClient.activate("my_experiment", user_id); if (variation != null) { if (variation.is("control")) { // Execute code for variation A } else if (variation.is("treatment")) { // Execute code for variation B } } else { // Execute default code } // Track conversion event eyeofcloudClient.track("my_conversion", user_id);
Example Code
import com.eyeofcloud.ab.Eyeofcloud; // Get an Eyeofcloud client EyeofcloudClient eyeofcloudClient = eyeofcloudManager.getEyeofcloud(); // Activate user in an experiment Variation variation = eyeofcloudClient.activate("my_experiment", "user_id"); if (variation != null) { if (variation.is("control")) { // Execute code for variation A } else if (variation.is("treatment")) { // Execute code for variation B } } else { // Execute default code } // Track conversion event eyeofcloudClient.track("my_conversion", user_id);
Example Code
require "eyeofcloud" # Initialize an Eyeofcloud client eyeofcloud_client = Eyeofcloud::Project.new(datafile) # Activate user in an experiment variation = eyeofcloud_client.activate("my_experiment", user_id) if variation == 'control' # Execute code for variation A elsif variation == 'treatment' # Execute code for variation B else # Execute default code end # Track conversion event eyeofcloud_client.track("my_conversion", user_id)
Example Code
var eyeofcloud = require('eyeofcloud-server-sdk'); // Initialize an Eyeofcloud client var eyeofcloudClient = eyeofcloud.createInstance({ datafile: datafile }); // Activate user in an experiment var variation = eyeofcloudClient.activate("my_experiment", userId); if (variation === 'control') { // Execute code for variation A } else if (variation === 'treatment') { // Execute code for variation B } else { // Execute default code } // Track conversion event eyeofcloudClient.track("my_conversion", userId);
Example Code
var eyeofcloud = require('eyeofcloud-client-sdk'); // Initialize an Eyeofcloud client var eyeofcloudClientInstance = eyeofcloud.createInstance({ datafile: datafile }); // ALTERNATIVELY, if you don't use CommonJS or npm, you can install the minified snippet and use the globally exported varible as follows: var eyeofcloudClientInstance = window.eyeofcloudClient.createInstance({ datafile: datafile }); // Activate user in an experiment var variation = eyeofcloudClientInstance.activate("my_experiment", userId); if (variation === 'control') { // Execute code for variation A } else if (variation === 'treatment') { // Execute code for variation B } else { // Execute default code } // Track conversion event eyeofcloudClientInstance.track("my_conversion", userId);
Example Code
use Eyeofcloud\Eyeofcloud; // Initialize an Eyeofcloud client $eyeofcloudClient = new Eyeofcloud($datafile); // Activate user in an experiment $variation = $eyeofcloudClient->activate('my_experiment', $userId); if ($variation == 'control') { // Execute code for variation A } elseif ($variation == 'treatment') { // Execute code for variation B } else { // Execute default code } // Track conversion event $eyeofcloudClient->track('my_conversion', $userId);
Example Code
var eocmanager = require('eyeofcloud-client-sdk'); onLoad: function(){ var that = this; app.getOpenId(function(openId){ // Initialize an Eyeofcloud client eocmanager.getInstance().then(function(eyeofcloudClientInstance){ // Activate user in an experiment var variation = eyeofcloudClientInstance.activate('experiment',openId); if ('variationA' == variation) { // Execute code for variation A } else if ('variationB' == variation) { // Execute code for variation B } else { // Execute default code } // Track conversion event eyeofcloud.track("my_conversion", userId); }) }) }
Example Code
// Initialize an Eyeofcloud manager EOCManager *eocManager = [EOCManager init:^(EOCManagerBuilder * _Nullable builder) { builder.projectId = @"projectId"; }]; // Initialize an Eyeofcloud client by asynchronously downloading the datafile [eocManager initializeWithCallback:^(NSError * _Nullable error, EOCClient * _Nullable client) { // Activate user in an experiment EOCVariation *variation = [client activate:@"my_experiment" userId:@"userId"]; if ([variation.variationKey isEqualToString:@"control"]) { // Execute code for the control } else if ([variation.variationKey isEqualToString:@"treatment"]) { // Execute code for the treatment } else { // Execute default code } // Track conversion event [client track:@"my_conversion" userId:@"userId"]; }];
Example Code
// Initialize an Eyeofcloud manager let eyeofcloudManager : EOCManager? = EOCManager.init {(builder) in builder!.projectId = "projectId" } // Initialize an Eyeofcloud client by asynchronously downloading the datafile eyeofcloudManager?.initialize(callback: { [weak self] (error, eyeofcloudClient) in // Activate user in an experiment if let variation = eyeofcloudClient?.activate("my_experiment", userId: "userId") { if (variation.variationKey == "control") { // Execute code for the control } else if (variation.variationKey == "treatment") { // Execute code for the treatment } } else { // execute default code } // Track conversion event eyeofcloudClient?.track("my_conversion", userId: "userId") })
安装
Python SDK的安装请注册云眼后进入控制台 > 业务优化 > SDK下载与安装查看详细指导。
JAVA SDK的安装请注册云眼后进入控制台 > 业务优化 > SDK下载与安装查看详细指导。
Ruby SDK的安装请注册云眼后进入控制台 > 业务优化 > SDK下载与安装查看详细指导。
Node SDK的安装请注册云眼后进入控制台 > 业务优化 > SDK下载与安装查看详细指导。
JavaScript SDK的安装请注册云眼后进入控制台 > 业务优化 > SDK下载与安装查看详细指导。
PHP SDK的安装请注册云眼后进入控制台 > 业务优化 > SDK下载与安装查看详细指导。
微信小程序 SDK的安装请注册云眼后进入控制台 > 业务优化 > SDK下载与安装查看详细指导。
Objective-C SDK的安装请注册云眼后进入控制台 > 业务优化 > SDK下载与安装查看详细指导。
Swift SDK的安装请注册云眼后进入控制台 > 业务优化 > SDK下载与安装查看详细指导。
Android SDK的安装请注册云眼后进入控制台 > 业务优化 > SDK下载与安装查看详细指导。
数据文件
SDK 在初始化时需要读取和解析数据文件。
数据文件采用JSON格式,包含了运行优化方案的所有信息,因此在调用activate
和track
方法时无需进行任何网络请求。
除非正在对云眼SDK进行二次开发,否则不需要直接与数据文件进行交互,云眼SDK会在解析数据文件后提供与云眼交互所需的所有接口。
Example datafile
{ "accountId": "12345", "projectId": "23456", "revision": "6", "version": "2", "experiments": [ { "key": "my_experiment", "id": "45678", "layerId": "34567", "status": "Running", "variations": [ { "id": "56789", "key": "control" }, { "id": "67890", "key": "treatment" } ], "trafficAllocation": [ { "entityId": "56789", "endOfRange": 5000 }, { "entityId": "67890", "endOfRange": 10000 } ], "audienceIds": [], "forcedVariations": {} } ], "events": [ { "experimentIds": [ "34567" ], "id": "56789", "key": "my_conversion" } ], "audiences": [], "attributes": [], "groups": [] }
Example datafile
{ "accountId": "12345", "projectId": "23456", "revision": "6", "version": "2", "experiments": [ { "key": "my_experiment", "id": "45678", "layerId": "34567", "status": "Running", "variations": [ { "id": "56789", "key": "control" }, { "id": "67890", "key": "treatment" } ], "trafficAllocation": [ { "entityId": "56789", "endOfRange": 5000 }, { "entityId": "67890", "endOfRange": 10000 } ], "audienceIds": [], "forcedVariations": {} } ], "events": [ { "experimentIds": [ "34567" ], "id": "56789", "key": "my_conversion" } ], "audiences": [], "attributes": [], "groups": [] }
Example datafile
{ "accountId": "12345", "projectId": "23456", "revision": "6", "version": "2", "experiments": [ { "key": "my_experiment", "id": "45678", "layerId": "34567", "status": "Running", "variations": [ { "id": "56789", "key": "control" }, { "id": "67890", "key": "treatment" } ], "trafficAllocation": [ { "entityId": "56789", "endOfRange": 5000 }, { "entityId": "67890", "endOfRange": 10000 } ], "audienceIds": [], "forcedVariations": {} } ], "events": [ { "experimentIds": [ "34567" ], "id": "56789", "key": "my_conversion" } ], "audiences": [], "attributes": [], "groups": [] }
Example datafile
{ "accountId": "12345", "projectId": "23456", "revision": "6", "version": "2", "experiments": [ { "key": "my_experiment", "id": "45678", "layerId": "34567", "status": "Running", "variations": [ { "id": "56789", "key": "control" }, { "id": "67890", "key": "treatment" } ], "trafficAllocation": [ { "entityId": "56789", "endOfRange": 5000 }, { "entityId": "67890", "endOfRange": 10000 } ], "audienceIds": [], "forcedVariations": {} } ], "events": [ { "experimentIds": [ "34567" ], "id": "56789", "key": "my_conversion" } ], "audiences": [], "attributes": [], "groups": [] }
Example datafile
{ "accountId": "12345", "projectId": "23456", "revision": "6", "version": "2", "experiments": [ { "key": "my_experiment", "id": "45678", "layerId": "34567", "status": "Running", "variations": [ { "id": "56789", "key": "control" }, { "id": "67890", "key": "treatment" } ], "trafficAllocation": [ { "entityId": "56789", "endOfRange": 5000 }, { "entityId": "67890", "endOfRange": 10000 } ], "audienceIds": [], "forcedVariations": {} } ], "events": [ { "experimentIds": [ "34567" ], "id": "56789", "key": "my_conversion" } ], "audiences": [], "attributes": [], "groups": [] }
Example datafile
{ "accountId": "12345", "projectId": "23456", "revision": "6", "version": "2", "experiments": [ { "key": "my_experiment", "id": "45678", "layerId": "34567", "status": "Running", "variations": [ { "id": "56789", "key": "control" }, { "id": "67890", "key": "treatment" } ], "trafficAllocation": [ { "entityId": "56789", "endOfRange": 5000 }, { "entityId": "67890", "endOfRange": 10000 } ], "audienceIds": [], "forcedVariations": {} } ], "events": [ { "experimentIds": [ "34567" ], "id": "56789", "key": "my_conversion" } ], "audiences": [], "attributes": [], "groups": [] }
Example datafile
{ "accountId": "12345", "projectId": "23456", "revision": "6", "version": "2", "experiments": [ { "key": "my_experiment", "id": "45678", "layerId": "34567", "status": "Running", "variations": [ { "id": "56789", "key": "control" }, { "id": "67890", "key": "treatment" } ], "trafficAllocation": [ { "entityId": "56789", "endOfRange": 5000 }, { "entityId": "67890", "endOfRange": 10000 } ], "audienceIds": [], "forcedVariations": {} } ], "events": [ { "experimentIds": [ "34567" ], "id": "56789", "key": "my_conversion" } ], "audiences": [], "attributes": [], "groups": [] }
Example datafile
{ "accountId": "12345", "projectId": "23456", "revision": "6", "version": "2", "experiments": [ { "key": "my_experiment", "id": "45678", "layerId": "34567", "status": "Running", "variations": [ { "id": "56789", "key": "control" }, { "id": "67890", "key": "treatment" } ], "trafficAllocation": [ { "entityId": "56789", "endOfRange": 5000 }, { "entityId": "67890", "endOfRange": 10000 } ], "audienceIds": [], "forcedVariations": {} } ], "events": [ { "experimentIds": [ "34567" ], "id": "56789", "key": "my_conversion" } ], "audiences": [], "attributes": [], "groups": [] }
Example datafile
{ "accountId": "12345", "projectId": "23456", "revision": "6", "version": "2", "experiments": [ { "key": "my_experiment", "id": "45678", "layerId": "34567", "status": "Running", "variations": [ { "id": "56789", "key": "control" }, { "id": "67890", "key": "treatment" } ], "trafficAllocation": [ { "entityId": "56789", "endOfRange": 5000 }, { "entityId": "67890", "endOfRange": 10000 } ], "audienceIds": [], "forcedVariations": {} } ], "events": [ { "experimentIds": [ "34567" ], "id": "56789", "key": "my_conversion" } ], "audiences": [], "attributes": [], "groups": [] }
Example datafile
{ "accountId": "12345", "projectId": "23456", "revision": "6", "version": "2", "experiments": [ { "key": "my_experiment", "id": "45678", "layerId": "34567", "status": "Running", "variations": [ { "id": "56789", "key": "control" }, { "id": "67890", "key": "treatment" } ], "trafficAllocation": [ { "entityId": "56789", "endOfRange": 5000 }, { "entityId": "67890", "endOfRange": 10000 } ], "audienceIds": [], "forcedVariations": {} } ], "events": [ { "experimentIds": [ "34567" ], "id": "56789", "key": "my_conversion" } ], "audiences": [], "attributes": [], "groups": [] }
数据文件位置
可以从云眼的控制台 > SDK下载与安装中获取数据文件的URL。
Example Code
// Use this code to get the URL of the datafile to fetch [EOCDatafileManagerUtility projectConfigURLPath:@"<PROJ-ID-STRING>"];
Example Code
// Use this code to get the URL of the datafile to fetch EOCDatafileManagerUtility.projectConfigURLPath("<PROJ-ID-STRING>")
Example Code
// Use this code to get the URL of the datafile to fetch EyeofcloudManager.getDatafileUrl(PROJECT_ID);
同步
为了接收试验更新的通知,SDK需要定期同步云眼服务器上的数据文件。
Android SDK包含了一个 EyeofcloudManager
类,可用于定时地异步地从云眼下载数据文件。
右边的示例代码示范了如何在 Application
子类的 onCreate
方法中实例化一个 EyeofcloudManager
对象。EyeofcloudManager
类也可以用于依赖注入框架,如 Dagger
和Guice
。
EyeofcloudManager.builder()
方法用于实例化一个 EyeofcloudManager
对象。可以通过给builder传参来配置Android SDK。
如果SDK向云眼发送事件失败,事件将会被存在消息队列中。.withEventHandlerDispatchInterval(long interval, TimeUnit)
方法控制SDK向云眼发送消息队列中的事件的频率,但当消息队列中没有待发送的事件时,该动作将取消。发送动作发生在Android服务中,即使用户把APP运行在后台。默认值: 1L
,TimeUnit.Day
.withDataFileDownloadInterval(long interval, TimeUnit)
方法控制SDK尝试同步数据文件的频率。无论APP是否启动,同步动作将通过Android服务在后台执行,这将有助于确保数据文件的实时更新。该动作将会按设定的频率定时执行。默认值: 1L
,TimeUnit.Day
同时运行多个Site的优化方案
可以在云眼创建多个Site,并在APP上同时所有Site的优化方案。实践时,一个 EyeofcloudManager
实例负责一个Site ID即可。数据文件的缓存、定时任务的设定还有Eyeofcloud实例将按Site ID进行管理和维护。
注意: 对于以上关于同步的实践,也可以选择实例化一个 Eyeofcloud
对象调用 .Eyeofcloud.builder(String datafile, EventHandler)
方法来获取数据文件,并且可以选择使用默认的 EventHandler
实现或者自定义的实现。详细内容请看 SDK配置。
Objective-C SDK包含了一个 EOCManager
类,用于管理SDK所有的配置项及状态。EOCManager
可用于为优化方案生成 Eyeofcloud 实例。 EOCManager
负责处理SDK的网络任务,包括从云眼同步SDK的数据文件。
初始化 EOCManager
实例需要一个 EOCDatafileManager
实例作为参数传入,EOCDatafileManager
类用于定期从Eyeofcloud下载数据文件,其中EOCDatafileManager
类包含以下几种数据文件管理配置项:
EOCDatafileManagerDefault
:在后台定期从云眼下载数据文件。下载动作包括轮询的时间间隔(默认为2分钟),并在数据文件更新时将数据文件保存在设备上。EOCDatafileManagerBasic
:下载数据文件但不包括轮询和保存的基本实现。EOCDatafileMangerNoOp
:没有下载数据文件的操作。
可以在AppDelegate
中的didFinishLoadingWithOptions
方法内创建EOCManager
实例,请参阅右侧的代码示例。初始化EOCManager
类时会使用默认的EOCDatafileManager
类,也可以使用自定义的文件管理类来作为EOCManager
初始化时的参数并赋值给builder
Swift SDK包含了一个 EOCManager
类,用于管理SDK所有的配置项及状态。EOCManager
可用于为优化方案生成 Eyeofcloud 实例。 EOCManager
负责处理SDK的网络任务,包括从云眼同步SDK的数据文件。
初始化 EOCManager
实例需要一个 EOCDatafileManager
实例作为参数传入,EOCDatafileManager
类用于定期从Eyeofcloud下载数据文件,其中EOCDatafileManager
类包含以下几种数据文件管理配置项:
EOCDatafileManagerDefault
:在后台定期从云眼下载数据文件。下载动作包括轮询的时间间隔(默认为2分钟),并在数据文件更新时将数据文件保存在设备上。EOCDatafileManagerBasic
:下载数据文件但不包括轮询和保存的基本实现。EOCDatafileMangerNoOp
:没有下载数据文件的操作。
可以在AppDelegate
中的didFinishLoadingWithOptions
方法内创建EOCManager
实例,请参阅右侧的代码示例。初始化EOCManager
类时会使用默认的EOCDatafileManager
类,也可以使用自定义的文件管理类来作为EOCManager
初始化时的参数并赋值给builder
Example Code
public class MyApplication extends Application { private EyeofcloudManager eyeofcloudManager; public EyeofcloudManager getEyeofcloudManager() { return eyeofcloudManager; } @Override public void onCreate() { super.onCreate(); eyeofcloudManager = EyeofcloudManager.builder() .withEventHandlerDispatchInterval(1, TimeUnit.DAYS) .withDataFileDownloadInterval(1, TimeUnit.DAYS) .build(); } }
Example Code
EOCDatafileManagerDefault *datafileManager = [EOCDatafileManagerDefault initWithBuilderBlock:^(EOCDatafileManagerBuilder * _Nullable builder) { builder.projectId = @"1234"; builder.datafileFetchInterval = kDatafileDownloadInterval; }]; EOCManager *eocManager = [EOCManager initWithBuilderBlock:^(EOCManagerBuilder * _Nullable builder) { builder.projectId = @"1234"; builder.datafileManager = datafileManager; }];
Example Code
let datafileManager: EOCDatafileManagerDefault? = EOCDatafileManagerDefault.initWithBuilderBlock({ (builder) in builder!.projectId = "1234" builder!.datafileFetchInterval = kDatafileDownloadInterval }) let eyeofcloudManager: EOCManager? = EOCManager.initWithBuilderBlock({ (builder) in builder!.projectId = "1234" builder!.datafileManager = datafileManager })
Webhooks
如果正在用服务器端应用程序管理数据文件,建议配置webhooks来维护最新版本的数据文件。只要相应的项目被修改,提供的端点将被发送一个POST请求。只要数据文件被更新,必须重新实例化SDK中的Eyeofcloud对象,以使更改生效。
可以通过“设置”>“ Webhooks”来设置 webhook,并添加webhook服务应响应的URL。
webhook有效负载结构如下。
{
"idSite": 1234,
"timestamp": 1590196904,
"event": "project.datafile_updated",
"data": {
"revision": 1,
"origin_url": "/editor/config/json/fullstack/1234.json"
}
}
目前,云眼平台只支持project.datafile_updated
一种事件类型.
EOCManager
的初始化方法来创建一个 EyeofcloudClient
对象来进行数据文件的同步,详细内容请参阅 初始化 部分。
EOCManager
的初始化方法来创建一个 EyeofcloudClient
对象来进行数据文件的同步,详细内容请参阅 初始化 部分。
EOCManager
的初始化方法来创建一个 EyeofcloudClient
对象来进行数据文件的同步,详细内容请参阅 初始化 部分。
初始化Eyeofcloud实例
在0.1.1及更高版本的SDK中,可以选择赋值 skip_json_validation
属性值为 True
以便在云眼实例化时跳过数据文件的JSON模式验证。跳过JSON模式验证增强了实例化性能。 skip_json_validation
只有在从REST API或CDN中提取数据文件时,才应使用该属性。
在0.1.1及更高版本的SDK中,可以选择赋值 skip_json_validation
属性值为 true
以便在云眼实例化时跳过数据文件的JSON模式验证。跳过JSON模式验证增强了实例化性能。 skip_json_validation
只有在从REST API或CDN中提取数据文件时,才应使用该属性。
除了datafile,还需提供一个 EventHandler
对象作为 Eyeofcloud.builder
方法的参数。可以使用默认的EventHandler类,也可以使用自定义实现,详细内容请参阅 Event dispatcher 部分内容。
如果datafile内容格式不对,或者内容不合法,Eyeofcloud.builder
会抛出一个 ConfigParseException
类的异常。
可以选择赋值 skipJSONValidation
属性值为 true
以便在云眼实例化时跳过数据文件的JSON模式验证。跳过JSON模式验证增强了实例化性能。 skipJSONValidation
只有在从REST API或CDN中提取数据文件时,才应使用该属性。
可以选择赋值 skipJSONValidation
属性值为 true
以便在云眼实例化时跳过数据文件的JSON模式验证。跳过JSON模式验证增强了实例化性能。 skipJSONValidation
只有在从REST API或CDN中提取数据文件时,才应使用该属性。
可以选择赋值 skipJSONValidation
属性值为 true
以便在云眼实例化时跳过数据文件的JSON模式验证。跳过JSON模式验证增强了实例化性能。 skipJSONValidation
只有在从REST API或CDN中提取数据文件时,才应使用该属性。
当希望自定义datafile manager、event dispatcher、error handler、event dispatcher、logger以及 user profile时,要求分别采用EOCDatafileManager
、 EOCEventDispatcher
、 EOCErrorHandler
、 EOCEventDispatcher
、 EOCLogger
以及 EOCUserProfile
协议。
详细内容请参阅 初始化选项
当希望自定义datafile manager、event dispatcher、error handler、event dispatcher、logger以及 user profile时,要求分别采用EOCDatafileManager
、 EOCEventDispatcher
、 EOCErrorHandler
、 EOCEventDispatcher
、 EOCLogger
以及 EOCUserProfile
协议。
详细内容请参阅 初始化选项
Example Code
import eyeofcloud # Initialize an Eyeofcloud client eyeofcloud_client = eyeofcloud.Eyeofcloud(datafile) # Skip JSON schema validation (SDK versions 0.1.1 and above) eyeofcloud_client = eyeofcloud.Eyeofcloud(datafile, skip_json_validation=True)
Example Code
import com.eyeofcloud.ab.Eyeofcloud; import com.eyeofcloud.ab.config.parser.ConfigParseException; import com.eyeofcloud.ab.event.AsyncEventHandler; import com.eyeofcloud.ab.event.EventHandler; // Creates an async event handler with a max buffer of // 20,000 events and a single dispatcher thread EventHandler eventHandler = new AsyncEventHandler(20000, 1); Eyeofcloud eyeofcloudClient; try { // Initialize an Eyeofcloud client eyeofcloudClient = Eyeofcloud.builder(datafile, eventHandler).build(); } catch (ConfigParseException e) { // Handle exception gracefully return; }
Example Code
final EyeofcloudManager eyeofcloudManager = ((MyApplication) getApplication()).getEyeofcloudManager(); EyeofcloudClient eyeofcloud = eyeofcloudManager.getEyeofcloud();
Example Code
require "eyeofcloud" # Initialize an Eyeofcloud client eyeofcloud_client = Eyeofcloud::Project.new(datafile) # Skip JSON schema validation (SDK versions 0.1.1 and above) eyeofcloud_client = Eyeofcloud::Project.new(datafile, nil, nil, nil, true)
Example Code
var eyeofcloud = require('eyeofcloud-server-sdk'); // Or ES6 import eyeofcloud from 'eyeofcloud-server-sdk' // Initialize an Eyeofcloud client var eyeofcloudClient = eyeofcloud.createInstance({ datafile: datafile }); // Skip JSON schema validation for the datafile var eyeofcloudClient = eyeofcloud.createInstance({ datafile: datafile, skipJSONValidation: true });
Example Code
use Eyeofcloud\Eyeofcloud; // Initialize an Eyeofcloud client $eyeofcloudClient = new Eyeofcloud($datafile); // Skip JSON schema validation $eyeofcloudClient = new Eyeofcloud($datafile, null, null, null, true);
Example Code
var eyeofcloud = require('eyeofcloud-client-sdk'); // Or ES6 import eyeofcloud from 'eyeofcloud-client-sdk'; // Initialize an Eyeofcloud client var eyeofcloudClientInstance = eyeofcloud.createInstance({ datafile: datafile }); // Skip JSON schema validation for the datafile var eyeofcloudClientInstance = eyeofcloud.createInstance({ datafile: datafile, skipJSONValidation: true });
Example Code
var eyeofcloud = require('eyeofcloud-client-sdk'); // Initialize an Eyeofcloud client var eyeofcloudClientInstance = eyeofcloud.createInstance({ datafile: datafile }); // Skip JSON schema validation for the datafile var eyeofcloudClientInstance = eyeofcloud.createInstance({ datafile: datafile, skipJSONValidation: true });
Example Code
EOCClient *eyeofcloudClient = [eyeofcloudManager initializeWithDatafile:datafile];
Example Code
let eyeofcloudClient: EOCClient? = eyeofcloudManager?.initialize(withDatafile:jsonDatafile!)
初始化选项
依据APP中激活优化方案的地方的不同,初始化一个Eyeofcloud实例的方式也不一样。
在第一个Activity激活优化方案
在 EyeofcloudManager
作为一个字段存储在 Application
的实现中,并提供了一个getter方法,使得可以在第一个Activity中取得它的情况下:首先,通过调用 Activity#getApplication()
方法获取 Application
的实例。下一步,将得到的 Application
实例的类型转换为 Application
实例的类型(右侧的例子中是 MyApplication
)。然后,通过getter方法获取EyeofcloudManager实例。Servic
和 Fragment
也有 .getApplication()
方法。
当APP第一次启动时,Android SDK并没有 datafile 的缓存,因此需要通过网络请求下载,网络请求不应该发生在主线程上,所以Eyeofcloud实例必须被异步引入。所以,Eyeofcloud实例的引入可以放在 Activity#onStart
上或者别的在Activity之外的地方。
在第一次启动APP时在第一个Activity中同步激活优化方案
如果确实需要在没有datafile缓存的情况下在第一个Activity中激活优化方案的话,可以将datafile预先编译好,而无需进行网络请求即可。
在后续的Activitys、Fragments或者Services中激活优化方案
请查看右侧代码示例。
EOCManager
类提供了多种初始化Eyeofcloud实例的方法。
异步调用
调用 initializeClientWithCallback
方法异步从云眼CDN下载datafile并初始化 Eyeofcloud
实例。
同步调用 - 本地缓存
调用 initializeClient
方法同步从本地缓存中获取datafile并初始化 Eyeofcloud
实例。如果从本地缓存获取datafile失败,该方法将返回一个空实例。
同步调用 - 代码变量
调用 initializeClientWithDatafile
同步地使用代码中的显式datafile变量来初始化 Eyeofcloud
实例。如果初始化失败,将尝试从本地缓存中初始化。如果从本地缓存中初始化失败,方法将返回一个空实例。
EOCManager
类提供了多种初始化Eyeofcloud实例的方法。
异步调用
调用 initializeClientWithCallback
方法异步从云眼CDN下载datafile并初始化 Eyeofcloud
实例。
同步调用 - 本地缓存
调用 initializeClient
方法同步从本地缓存中获取datafile并初始化 Eyeofcloud
实例。如果从本地缓存获取datafile失败,该方法将返回一个空实例。
同步调用 - 代码变量
调用 initializeClientWithDatafile
同步地使用代码中的显式datafile变量来初始化 Eyeofcloud
实例。如果初始化失败,将尝试从本地缓存中初始化。如果从本地缓存中初始化失败,方法将返回一个空实例。
有关如何自定义Eyeofcloud实例的完整详细信息,请参阅: SDK配置
Example Code
public class FirstActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_first); EyeofcloudManager eyeofcloudManager = ((MyApplication) getApplication()).getEyeofcloudManager(); eyeofcloudManager.initialize(this, new EyeofcloudStartListener() { @Override public void onStart(EyeofcloudClient eyeofcloud) { assert eyeofcloud == eyeofcloudManager.getEyeofcloud(); Intent intent = new Intent(FirstActivity.this, SubsequentActivity.class); startActivity(intent); } }); } } public class FirstActivitySynchronousStart extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_first); EyeofcloudManager eyeofcloudManager = ((MyApplication) getApplication()).getEyeofcloudManager(); assert eyeofcloudManager.getEyeofcloud() == null; EyeofcloudClient eyeofcloud = eyeofcloudManager.initialize(MyActivity.this, R.raw.data_file); assert eyeofcloud != null; } } public class SubsequentActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_subsequent); final EyeofcloudManager eyeofcloudManager = ((MyApplication) getApplication()).getEyeofcloudManager(); EyeofcloudClient eyeofcloud = eyeofcloudManager.getEyeofcloud(); assert eyeofcloud != null; } }
优化方案
调用activate
方法即可在代码中激活及运行优化方案。
如果需要在激活优化方案时向云眼发送一个PageView的话,可以调用activate
方法。调用activate
方法需要两个参数:优化方案的名称和用户ID。
调用该函数时,首先判断用户是否满足优化方案的受众条件。如果满足,优化方案就会开始运行,然后基于分流情况抽选优化方案的优化版本,并向云眼发送一次PageView。最后函数返回被抽中的优化版本的名称。
activate
方法返回None
.
activate
方法返回None
.
activate
方法返回None
.
activate
方法返回None
.
activate
方法返回None
.
activate
方法返回None
.
activate
方法返回None
.
activate
方法返回None
.
activate
方法返回None
.
activate
方法返回None
.
在使用SDK的接口编写代码时,请确保代码满足没有任何优化方案被激活的情况,比如执行默认的优化版本。
activate
方法。在用户满足优化方案的受众条件的情况下,SDK会发送一次PageView事件到云眼服务器,以记录优化方案的运行及用户的信息。在用户不满足优化方案的受众条件的情况下,SDK不会发送任何记录。Example Code
experiment_key = 'my_experiment' user_id = 'user123' # Conditionally activate an experiment for the provided user variation = eyeofcloud_client.activate(experiment_key, user_id) if variation == 'control': # Execute code for control variation elif variation == 'treatment': # Execute code for treatment variation else: # Execute default code
Example Code
String experimentKey = "my_experiment"; String userId = "user123"; // Conditionally activate an experiment for the provided user Variation variation = eyeofcloudClient.activate(experimentKey, userId); if (variation != null) { if (variation.is("control")) { // Execute code for control variation } else if (variation.is("treatment")) { // Execute code for treatment variation } } else { // Execute default code }
Example Code
EyeofcloudClient eyeofcloudClient = eyeofcloudManager.getEyeofcloud(); String experimentKey = "my_experiment"; String userId = "user123"; // Conditionally activate an experiment for the provided user Variation variation = eyeofcloudClient.activate(experimentKey, userId); if (variation != null) { if (variation.is("control")) { // Execute code for control variation } else if (variation.is("treatment")) { // Execute code for treatment variation } } else { // Execute default code }
Example Code
experiment_key = 'my_experiment' user_id = 'user123' # Conditionally activate an experiment for the provided user variation = eyeofcloud_client.activate(experiment_key, user_id) if variation == 'control' # Execute code for control variation elsif variation == 'treatment' # Execute code for treatment variation else # Execute default code end
Example Code
var experimentKey = 'my_experiment'; var userId = 'user123'; // Conditionally activate an experiment for the provided user var variation = eyeofcloudClient.activate(experimentKey, userId); if (variation === 'control') { // Execute code for control variation } else if (variation === 'treatment') { // Execute code for treatment variation } else { // Execute default code }
Example Code
var experimentKey = 'my_experiment'; var userId = 'user123'; // Conditionally activate an experiment for the provided user var variation = eyeofcloudClientInstance.activate(experimentKey, userId); if (variation === 'control') { // Execute code for control variation } else if (variation === 'treatment') { // Execute code for treatment variation } else { // Execute default code }
Example Code
$experimentKey = 'my_experiment'; $userId = 'user123'; // Conditionally activate an experiment for the provided user $variation = $eyeofcloudClient->activate($experimentKey, $userId); if ($variation == 'control') { // Execute code for control variation } elseif ($variation == 'treatment') { // Execute code for treatment variation } else { # Execute default code }
Example Code
var experimentKey = 'my_experiment'; var userId = 'user123'; // Conditionally activate an experiment for the provided user var variation = eyeofcloudClientInstance.activate(experimentKey, userId); if ('variationA' == variation) { // Execute code for variation A } else if ('variationB' == variation) { // Execute code for variation B } else { // Execute default code }
Example Code
// Conditionally activate an experiment for the provided user EOCVariation *variation = [eyeofcloud activate:@"my_experiment" userId:@"user123"]; if ([variation.variationKey isEqualToString:@"control"]) { // Execute code for control variation } else if ([variation.variationKey isEqualToString:@"treatment"]) { // Execute code for treatment variation } else { // Execute default code }
Example Code
// Conditionally activate an experiment for the provided userId if let variation = eyeofcloud?.activate("my_experiment", userId: "user123") { if (variation.variationKey == "control") { // Execute code for control variation } else if (variation.variationKey == "treatment") { // Execute code for treatment variation } } else { // Execute default code }
用户属性
如果希望能够根据用户的属性对优化方案结果进行分段,那么在激活优化方案时包含参数attributes
即可。在向云眼发送记录时,云眼将记录这些属性值,以便可以在优化结果页面上通过这些属性对结果进行分段。
使用用户属性还可以将优化方案定位到在云眼控制台预先定义的特定受众群体中。如果优化方案定义了受众条件,云眼将会在激活优化方案时通过属性值评估用户是否满足受众条件,从而决定是否激活优化方案。
attributes
,如果试验里没有添加受众(表示所有用户都可以激活试验),这时attributes
对是否激活试验不起任何作用,但是attributes
仍可以传到云眼后台用于分段。attributes
,如果试验里添加的受众只使用了一部分用户属性,没有被使用的用户属性对是否激活试验不起任何作用,但是仍可以传到云眼后台用于分段。Example Code
experiment_key = 'my_experiment' user_id = 'user123' attributes = {'device': 'iPhone', 'ad_source': 'my_campaign'} # Conditionally activate an experiment for the provided user variation = eyeofcloud.activate(experiment_key, user_id, attributes)
Example Code
String experimentKey = "my_experiment"; String userId = "user123"; Map<String, String> attributes = new HashMap<String, String>(); attributes.put("DEVICE", "iPhone"); attributes.put("AD_SOURCE", "my_campaign"); // Conditionally activate an experiment for the provided user Variation variation = eyeofcloud.activate(experimentKey, userId, attributes);
Example Code
EyeofcloudClient eyeofcloud = eyeofcloudManager.getEyeofcloud(); String experimentKey = "my_experiment"; String userId = "user123"; Map<String, String> attributes = new HashMap<String, String>(); attributes.put("DEVICE", "Nexus 6P"); attributes.put("AD_SOURCE", "my_campaign"); // Conditionally activate a experiment for the provided user Variation variation = eyeofcloud.activate(experimentKey, userId, attributes);
Example Code
experiment_key = 'my_experiment' user_id = 'user123' attributes = {'DEVICE' => 'iPhone', 'AD_SOURCE' => 'my_campaign'} # Conditionally activate an experiment for the provided user variation = eyeofcloud_client.activate(experiment_key, user_id, attributes)
Example Code
var experimentKey = 'my_experiment'; var userId = 'user123'; var attributes = { 'device': 'iphone', 'ad_source': 'my_campaign' }; // Conditionally activate an experiment for the provided user var variation = eyeofcloud.activate(experimentKey, userId, attributes);
Example Code
var experimentKey = 'my_experiment'; var userId = 'user123'; var attributes = { 'device': 'iphone', 'ad_source': 'my_campaign' }; // Conditionally activate an experiment for the provided user var variation = eyeofcloudClientInstance.activate(experimentKey, userId, attributes);
Example Code
$experimentKey = 'my_experiment'; $userId = 'user123'; $attributes = [ 'device' => 'iphone', 'ad_source' => 'my_campaign' ]; // Conditionally activate an experiment for the provided user $variation = $eyeofcloudClient->activate($experimentKey, $userId, $attributes);
Example Code
var experimentKey = 'my_experiment'; var userId = 'user123'; var attributes = { 'device': 'iphone', 'ad_source': 'my_campaign' }; // Conditionally activate an experiment for the provided user var variation = eyeofcloudClientInstance.activate(experimentKey, userId, attributes);
Example Code
NSDictionary *attributes = @{@"device" : @"iPhone", @"ad_source" : @"my_campaign"}; EOCVariation *variation = [eyeofcloud activate:@"my_experiment" userId:@"user123" attributes:attributes];
Example Code
let attributes = ["device" : "iPhone", "ad_source" : "my_campaign"] let variation: EOCVariation? = eyeofcloud?.activate("my_experiment", userId:"user123", attributes:attributes)
获取版本
在已经调用activate
方法根据用户ID激活了优化方案的情况下,如果想再次获取该优化方案中被抽中的版本名称而不向云眼发送重复的跟踪请求,可以参照右侧所示的代码。
Example Code
experiment_key = 'my_experiment' user_id = 'user123' # Get the active variation for the provided user variation = eyeofcloud_client.get_variation(experiment_key, user_id)
Example Code
String experimentKey = "my_experiment"; String userId = "user123"; Eyeofcloud eyeofcloudClient = eyeofcloudManager.getEyeofcloud(); // Get the active variation for the provided user Variation variation = eyeofcloudClient.getVariation(experimentKey, userId);
Example Code
String experimentKey = "my_experiment"; String userId = "user123"; // Get the active variation for the provided user Variation variation = eyeofcloudClient.getVariation(experimentKey, userId);
Example Code
experiment_key = 'my_experiment' user_id = 'user123' # Get the active variation for the provided user variation = eyeofcloud_client.get_variation(experiment_key, user_id)
Example Code
$experimentKey = 'my_experiment'; $userId = 'user123'; # Get the active variation for the provided user $variation = $eyeofcloudClient->getVariation($experimentKey, $userId);
Example Code
var experimentKey = 'my_experiment'; var userId = 'user123'; // Get the active variation for the provided user var variation = eyeofcloudClientInstance.getVariation(experimentKey, userId);
Example Code
var experimentKey = 'my_experiment'; var userId = 'user123'; // Get the active variation for the provided user var variation = eyeofcloudClient.getVariation(experimentKey, userId);
Example Code
var experimentKey = 'my_experiment'; var userId = 'user123'; // Get the active variation for the provided user var variation = eyeofcloudClientInstance.getVariation(experimentKey, userId);
Example Code
// Get the active variation for an experiment for the provided user EOCVariation *variation = [eyeofcloud variation:@"my_experiment" userId:@"user123"];
Example Code
// Get the active variation for an experiment for the provided user let variation: EOCVariation? = eyeofcloud?.variation("my_experiment", userId:"user123")
事件
如右图所示,可以轻松地编写代码来跟踪事件的转化。
跟踪事件不需要优化方案和优化版本的名称作为参数:云眼后台只会对已被使用的事件进行跟踪。
要在优化结果页面上对结果进行分段,需要向track
方法传递在activate
方法中使用的相同用户属性。
此外,还可以向事件标签传递一个可选的事件键值对,键为事件名,值需为整型,将在优化方案的指标计算中使用。
此外,还可以向事件标签传递一个可选的事件键值对,键为事件名,值需为整型,将在优化方案的指标计算中使用。
此外,还可以向事件标签传递一个可选的事件键值对,键为事件名,值需为整型,将在优化方案的指标计算中使用。
此外,还可以向事件标签传递一个可选的事件键值对,键为事件名,值需为整型,将在优化方案的指标计算中使用。
此外,还可以传递一个可选的事件值,事件值需为整型,将在优化方案的指标计算中使用。
此外,还可以传递一个可选的事件值,事件值需为整型,将在优化方案的指标计算中使用。
此外,还可以传递一个可选的事件值,事件值需为整型,将在优化方案的指标计算中使用。
此外,还可以传递一个可选的事件值,事件值需为整型,将在优化方案的指标计算中使用。
此外,还可以传递一个可选的事件值,事件值需为整型,将在优化方案的指标计算中使用。
此外,还可以传递一个可选的事件值,事件值需为整型,将在优化方案的指标计算中使用。
activate
方法被调用后对事件进行记录。如果在优化结果页面上没有看到期望的事件转化结果,请检查代码,确保在调用track
方法之前,已调用activate
方法激活优化方案。
使用其他语言的SDK跟踪同一事件
可以使用云眼任何SDK跟踪同一事件,因此可以运行跨多个应用程序,服务或设备的优化方案。所有的SDK都具有相同的版本抽选和分流逻辑,所以如果使用相同的数据文件和用户ID,在任何SDK中,都将获得相同的优化方案运行结果和事件跟踪效果。
例如,如果在服务器上运行试验,可以使用云眼Python,Java,Ruby或Node SDK 激活优化方案,同时,可以使用云眼JavaScript,Objective-C或Android SDK 跟踪客户端的用户操作。
如果计划在同一个项目中使用多个SDK,请确保所有SDK都使用相同的数据文件和用户ID。
Example Code
event_key = 'my_conversion' user_id = 'user123' attributes = {'device': 'iPhone', 'ad_source': 'my_campaign'} event_tags = {'category': 'shoes', 'purchasePrice': 64.32, 'revenue': 500} # Track a conversion event for the provided user eyeofcloud_client.track(event_key, user_id) # Track a conversion event for the provided user with attributes eyeofcloud_client.track(event_key, user_id, attributes); # Track a conversion event for the provided user with event tags and revenue value of 500 eyeofcloud_client.track(event_key, user_id, event_tags=event_tags); # Track a conversion event for the provided user with attributes, event tags and revenue value of 500 eyeofcloud_client.track(event_key, user_id, attributes, event_tags);
Example Code
String eventKey = "my_conversion"; String userId = "user123"; Map<String, String> attributes = new HashMap<String, String>(); attributes.put("DEVICE", "iPhone"); attributes.put("AD_SOURCE", "my_campaign"); // Track a conversion event for the provided user eyeofcloudClient.track(eventKey, userId); // Track a conversion event for the provided user with attributes eyeofcloudClient.track(eventKey, userId, attributes); // Track a conversion event for the provided user with attributes and event tags Map<String, Object> eventTags = new HashMap<String, Object>(); eventTags.put('category', 'shoes'); eyeofcloudClient.track(eventKey, userId, attributes, eventTags); // Track a conversion event for the provided user with attributes, event tags and revenue value of 500 eventTags.put('revenue', 500); // revenue is a reserved event tag keyword eyeofcloudClient.track(eventKey, userId, attributes, eventTags);
Example Code
String eventKey = "my_conversion"; String userId = "user123"; Eyeofcloud eyeofcloudClient = eyeofcloudManager.getEyeofcloud(); // Track a conversion event for the provided user eyeofcloudClient.track(eventKey, userId); // Track a conversion event for the provided user with attributes eyeofcloudClient.track(eventKey, userId, attributes); // Track a conversion event for the provided user with event value of 500 eyeofcloudClient.track(eventKey, userId, 500); // Track a conversion event for the provided user with attributes and event value of 500 eyeofcloudClient.track(eventKey, userId, attributes, 500);
Example Code
event_key = 'my_conversion' user_id = 'user123' # Track a conversion event for the provided user eyeofcloud_client.track(event_key, user_id) attributes = { 'device' => 'iPhone', 'adSource' => 'my_campaign' } # Track a conversion event for the provided user with attributes eyeofcloud_client.track(event_key, user_id, attributes) event_tags = { 'category' => 'shoes', 'purchasePrice' => 64.32, 'revenue' => 500 } # Track a conversion event for the provided user with event tags and revenue value of 500 eyeofcloud_client.track(event_key, user_id, nil, event_tags) # Track a conversion event for the provided user with attributes, event tags and revenue value of 500 eyeofcloud_client.track(event_key, user_id, attributes, event_tags)
Example Code
var eventKey = 'my_conversion'; var userId = 'user123'; // Track a conversion event for the provided user eyeofcloudClient.track(eventKey, userId); // Track a conversion event for the provided user with attributes var attributes = { device: 'iPhone', ad_source: 'my_campaign' }; eyeofcloudClient.track(eventKey, userId, attributes); // Track a conversion event for the provided user with attributes and event tags var eventTags = { category: 'shoes' }; eyeofcloudClient.track(eventKey, userId, attributes, eventTags) // Track a conversion event for the provided user with attributes, event tags and revenue value of 500 eventTags.put('revenue', 500); // use the reserved event tag "revenue" keyword eyeofcloudClient.track(eventKey, userId, attributes, eventTags);
Example Code
var eventKey = 'my_conversion'; var userId = 'user123'; // Track a conversion event for the provided user eyeofcloudClientInstance.track(eventKey, userId); // Track a conversion event for the provided user with attributes var attributes = { device: 'iPhone', ad_source: 'my_campaign' }; eyeofcloudClient.track(eventKey, userId, attributes); // Track a conversion event for the provided user with attributes and event tags var eventTags = { category: 'shoes' }; eyeofcloudClient.track(eventKey, userId, attributes, eventTags) // Track a conversion event for the provided user with attributes, event tags and revenue value of 500 eventTags.put('revenue', 500); // use the reserved event tag "revenue" keyword eyeofcloudClient.track(eventKey, userId, attributes, eventTags);
Example Code
$eventKey = 'my_conversion'; $userId = 'user123'; $attributes = [ 'device' => 'iphone', 'ad_source' => 'my_campaign' ]; $eventTags = [ 'category' => 'shoes', 'purchasePrice' => 64.32, 'revenue' => 500 ]; // Track a conversion event for the provided user $eyeofcloudClient->track($eventKey, $userId); // Track a conversion event for the provided user with attributes $eyeofcloudClient->track($eventKey, $userId, $attributes); // Track a conversion event for the provided user with event tags and revenue value of 500 $eyeofcloudClient->track($eventKey, $userId, null, $eventTags); // Track a conversion event for the provided user with attributes, event tags and revenue value of 500 $eyeofcloudClient->track($eventKey, $userId, $attributes, $eventTags);
Example Code
var eventKey = 'my_conversion'; var userId = 'user123'; // Track a conversion event for the provided user eyeofcloudClientInstance.track(eventKey, userId); // Track a conversion event for the provided user with attributes var attributes = { device: 'iPhone', ad_source: 'my_campaign' }; eyeofcloudClient.track(eventKey, userId, attributes); // Track a conversion event for the provided user with attributes and event tags var eventTags = { category: 'shoes' }; eyeofcloudClient.track(eventKey, userId, attributes, eventTags) // Track a conversion event for the provided user with attributes, event tags and revenue value of 500 eventTags.put('revenue', 500); // use the reserved event tag "revenue" keyword eyeofcloudClient.track(eventKey, userId, attributes, eventTags);
Example Code
NSDictionary *attributes = @{@"device" : @"iPhone", @"ad_source" : @"my_campaign"}; // Track a conversion event for the provided user [eyeofcloud track:@"my_conversion" userId:@"user123"]; // Track a conversion event for the provided user with attributes [eyeofcloud track:@"my_conversion" userId:@"user123" attributes:attributes]; // Track a conversion event for the provided user with event value of 500 [eyeofcloud track:@"my_conversion" userId:@"user123" eventValue:500]; // Track a conversion event for the provided user with attributes and event value of 500 [eyeofcloud track:@"my_conversion" userId:@"user123" attributes:attributes eventValue:500];
Example Code
let attributes = ["device" : "iPhone", "ad_source" : "my_campaign"] // Track a conversion event for the provided user eyeofcloud?.track("my_conversion", userId:"user123") // Track a conversion event for the provided user with attributes eyeofcloud?.track("my_conversion", userId:"user123", attributes:attributes) // Track a conversion event for the provided user with event value of 500 eyeofcloud?.track("my_conversion", userId:"user123", eventValue:500) // Track a conversion event for the provided user with attributes and event value of 500 eyeofcloud?.track("my_conversion", userId:"user123", attributes:attributes, eventValue:500)
事件标签
事件标签是跟踪的获得转化的事件的上下文信息。例如,可以使用标签来描述产品被购买了、文章被阅读了或航班被预定了等事件转化的信息。
保留关键字
除了作为eventFeatures
参数时,以下关键字被保留,并将映射到事件的有效载荷:
revenue
- 作为试验指标计算中需要使用的整型值。
eventTags
暂时用不到,可以忽略此部分文档。
Example Code
event_key = 'my_conversion' user_id = 'user123' attributes = { 'device': 'iPhone', 'adSource': 'my_campaign' } event_tags = { 'category': 'shoes', 'purchasePrice': 64.32, 'revenue': 100 # reserved "revenue" keyword } # track event with user attributes and event tags eyeofcloud_client.track(event_key, user_id, attributes, event_tags) # track event with event tags and without user attributes eyeofcloud_client.track(event_key, user_id, event_tags=event_tags)
Example Code
String eventKey = "my_conversion"; String userId = "user123"; Map<String, String> attributes = new HashMap<String, String>(); attributes.put("DEVICE", "iPhone"); attributes.put("AD_SOURCE", "my_campaign"); Map<String, Object> eventTags = new HashMap<String, Object>(); eventTags.put("purchasePrice", 64.32f); eventTags.put("category", "shoes"); // reserved "revenue" keyword, eventTags.put("revenue", 100); eyeofcloud.track(eventKey, userId, attributes, eventTags);
Example Code
event_key = 'my_conversion' user_id = 'user123' attributes = { 'device' => 'iPhone', 'adSource' => 'my_campaign' } event_tags = { 'category' => 'shoes', 'purchasePrice' => 64.32, 'revenue' => 100 # reserved "revenue" keyword } # track event with user attributes and event tags eyeofcloud_client.track(event_key, user_id, attributes, event_tags) # track event with event tags and without user attributes eyeofcloud_client.track(event_key, user_id, nil, event_tags)
Example Code
$eventKey = 'my_conversion'; $userId = 'user123'; $attributes = [ 'device' => 'iphone', 'ad_source' => 'my_campaign' ]; $eventTags = [ 'category' => 'shoes', 'purchasePrice' => 64.32, 'revenue' => 500 # reserved "revenue" keyword ]; # track event with user attributes and event tags $eyeofcloudClient->track($eventKey, $userId, $attributes, $eventTags); # track event with event tags and without user attributes $eyeofcloudClient->track($eventKey, $userId, null, $eventTags);
Example Code
var eventKey = "my_conversion"; var userId = "user123"; var attributes = { DEVICE: 'iPhone', AD_SOURCE: 'my_campaign' }; var eventTags = { category: 'shoes', purchasePrice: 64.32, revenue: 100 // reserved "revenue" keyword }; eyeofcloud.track(eventKey, userId, attributes, eventTags);
Example Code
var eventKey = "my_conversion"; var userId = "user123"; var attributes = { DEVICE: 'iPhone', AD_SOURCE: 'my_campaign' }; var eventTags = { category: 'shoes', purchasePrice: 64.32, revenue: 100 // reserved "revenue" keyword }; eyeofcloud.track(eventKey, userId, attributes, eventTags);
Example Code
var eventKey = "my_conversion"; var userId = "user123"; var attributes = { DEVICE: 'iPhone', AD_SOURCE: 'my_campaign' }; var eventTags = { category: 'shoes', purchasePrice: 64.32, revenue: 100 // reserved "revenue" keyword }; eyeofcloud.track(eventKey, userId, attributes, eventTags);
变量
使用变量来使应用程序参数化,从而实时进行AB测试。
变量可以在应用程序中声明和初始化一次。将这些变量部署到生产环境后,可以随后对这些变量的不同值执行无限制的试验,而无需执行额外的代码部署。可以在编辑优化方案时控制变量,以便可以实时推出功能并调整应用程序的行为。
- variableKey:变量名称,唯一且为英文字符串,在云眼控制台->业务优化列表->编辑中定义。
- userId: 当前用户的标识。
- attributes (可选项): 当前用户的属性集合。
- activateExperiment: 如果设值为
true
,将会向云眼发送一个包含这个变量的优化版本的PageView。 - error (可选项): 指定当找不到对应variableKey的变量时返回的错误值。
注意: 当赋值activateExperiment
为true时,variable的getter方法会激活优化方案并向云眼发送一个PageView,从而可以用来替代 activate
方法。通过变量,可以不受限制的随时增加优化方案并运行。不过,如果在调用了 activate
方法后调用variable的getter方法时请注意赋值 activateExperiment
为false,以防止重复发送冗余的PageView。
- variableKey:变量名称,唯一且为英文字符串,在云眼控制台->业务优化列表->编辑中定义。
- userId: 当前用户的标识。
- activateExperiment: 如果设值为
true
,则激活试验,将会向云眼发送一个包含这个变量的优化版本的PageView;如果设值为false
,则仅获取变量值,不会向云眼发送一个包含这个变量的优化版本的PageView。 - attributes: 当前用户的属性集合。
如果优化方案使用了指定的变量,且当前用户满足优化方案的受众条件,则根据优化版本的抽选情况返回对应的变量值;如果variableKey对应的变量没有被任何一个优化版本使用,或者当前用户不满足优化版本的受众条件的话,则返回该变量的默认值。如果没有找到对应的variableKey,则返回null。
- variableKey:变量名称,唯一且为英文字符串,在云眼控制台->业务优化列表->编辑中定义。
- userId: 当前用户的标识。
- activateExperiment: 如果设值为
true
,则激活试验,将会向云眼发送一个包含这个变量的优化版本的PageView;如果设值为false
,则仅获取变量值,不会向云眼发送一个包含这个变量的优化版本的PageView。 - attributes: 当前用户的属性集合。
如果优化方案使用了指定的变量,且当前用户满足优化方案的受众条件,则根据优化版本的抽选情况返回对应的变量值;如果variableKey对应的变量没有被任何一个优化版本使用,或者当前用户不满足优化版本的受众条件的话,则返回该变量的默认值。如果没有找到对应的variableKey,则返回null。
- variableKey:变量名称,唯一且为英文字符串,在云眼控制台->业务优化列表->编辑中定义。
- userId: 当前用户的标识。
- activateExperiment: 如果设值为
true
,则激活试验,将会向云眼发送一个包含这个变量的优化版本的PageView;如果设值为false
,则仅获取变量值,不会向云眼发送一个包含这个变量的优化版本的PageView。 - attributes: 当前用户的属性集合。
如果优化方案使用了指定的变量,且当前用户满足优化方案的受众条件,则根据优化版本的抽选情况返回对应的变量值;如果variableKey对应的变量没有被任何一个优化版本使用,或者当前用户不满足优化版本的受众条件的话,则返回该变量的默认值。如果没有找到对应的variableKey,则返回null。
- variableKey:变量名称,唯一且为英文字符串,在云眼控制台->业务优化列表->编辑中定义。
- userId: 当前用户的标识。
- attributes (可选项): 当前用户的属性集合。
- activateExperiment: 如果设值为
true
,将会向云眼发送一个包含这个变量的优化版本的PageView。 - error (可选项): 指定当找不到对应variableKey的变量时返回的错误值。
注意: 当赋值activateExperiment
为true时,variable的getter方法会激活优化方案并向云眼发送一个PageView,从而可以用来替代 activate
方法。通过变量,可以不受限制的随时增加优化方案并运行。不过,如果在调用了 activate
方法后调用variable的getter方法时请注意赋值 activateExperiment
为false,以防止重复发送冗余的PageView。
- variableKey:变量名称,唯一且为英文字符串,在云眼控制台->业务优化列表->编辑中定义。
- userId: 当前用户的标识。
- attributes (可选项): 当前用户的属性集合。
- activateExperiment: 如果设值为
true
,将会向云眼发送一个包含这个变量的优化版本的PageView。 - error (可选项): 指定当找不到对应variableKey的变量时返回的错误值。
注意: 当赋值activateExperiment
为true时,variable的getter方法会激活优化方案并向云眼发送一个PageView,从而可以用来替代 activate
方法。通过变量,可以不受限制的随时增加优化方案并运行。不过,如果在调用了 activate
方法后调用variable的getter方法时请注意赋值 activateExperiment
为false,以防止重复发送冗余的PageView。
- variableKey:变量名称,唯一且为英文字符串,在云眼控制台->业务优化列表->编辑中定义。
- userId: 当前用户的标识。
- attributes (可选项): 当前用户的属性集合。
- activateExperiment: 如果设值为
true
,将会向云眼发送一个包含这个变量的优化版本的PageView。 - error (可选项): 指定当找不到对应variableKey的变量时返回的错误值。
注意: 当赋值activateExperiment
为true时,variable的getter方法会激活优化方案并向云眼发送一个PageView,从而可以用来替代 activate
方法。通过变量,可以不受限制的随时增加优化方案并运行。不过,如果在调用了 activate
方法后调用variable的getter方法时请注意赋值 activateExperiment
为false,以防止重复发送冗余的PageView。
Example Code
String userId = "user123"; // Get the value of a Boolean variable Boolean myVariable = eyeofcloudClient.getVariableBoolean("myVariable", userId, true, attributes); // Get the value of a Boolean variable without sending pageview Boolean myVariable = eyeofcloudClient.getVariableBoolean("myVariable", userId, false, attributes); // Get the value of a floating point variable Float myVariable = eyeofcloudClient.getVariableFloat("myVariable", userId, true, attributes); // Get the value of an integer variable Integer myVariable = eyeofcloudClient.getVariableInteger("myVariable", userId, true, attributes); // Get the value of a string variable String myVariable = eyeofcloudClient.getVariableString("myVariable", userId, true, attributes);
Example Code
String userId = "user123"; var attributes = { 'device': 'iphone', 'ad_source': 'my_campaign' }; // Get the value of a Boolean variable myVariable = eyeofcloudClient.getVariableBoolean("myVariable", userId, true, attributes); // Get the value of a Boolean variable without sending pageview myVariable = eyeofcloudClient.getVariableBoolean("myVariable", userId, false, attributes); // Get the value of a string variable myVariable = eyeofcloudClient.getVariable("myVariable", userId, true, attributes);
Example Code
String userId = "user123"; var attributes = { 'device': 'iphone', 'ad_source': 'my_campaign' }; // Get the value of a Boolean variable myVariable = eyeofcloudClient.getVariableBoolean("myVariable", userId, true, attributes); // Get the value of a Boolean variable without sending pageview myVariable = eyeofcloudClient.getVariableBoolean("myVariable", userId, false, attributes); // Get the value of a string variable myVariable = eyeofcloudClient.getVariable("myVariable", userId, true, attributes);
Example Code
NSDictionary *attributes = @{@"device" : @"iPhone", @"ad_source" : @"my_campaign"}; // Get the value of a boolean variable bool myVariable = [eyeofcloud variableBoolean:@"myVariable" userId:userId activateExperiment:True attributes:attributes]; // Get the value of a boolean variable without sending pageview bool myVariable = [eyeofcloud variableBoolean:@"myVariable" userId:userId activateExperiment:False attributes:attributes]; // Get the value of a double variable double myVariable = [eyeofcloud variableDouble:@"myVariable" userId:userId activateExperiment:True attributes:attributes]; // Get the value of an integer variable int myVariable = [eyeofcloud variableInteger:@"myVariable" userId:userId activateExperiment:True attributes:attributes]; // Get the value of a string variable NSString *myVariable = [eyeofcloud variableString:@"myVariable" userId:userId activateExperiment:True attributes:attributes];
Example Code
let attributes = ["device" : "iPhone", "ad_source" : "my_campaign"] // Get the value of a boolean variable let myVariable = eyeofcloud?.variableBoolean:("myVariable", userId:"user123", activateExperiment:true, attributes:attributes) // Get the value of a boolean variable without sending pageview let myVariable = eyeofcloud?.variableBoolean:("myVariable", userId:"user123", activateExperiment:false, attributes:attributes) // Get the value of a double variable let myVariable = eyeofcloud?.variableDouble:("myVariable", userId:"user123", activateExperiment:true, attributes:attributes) // Get the value of an integer variable let myVariable = eyeofcloud?.variableInteger:("myVariable", userId:"user123", activateExperiment:true, attributes:attributes) // Get the value of a string variable let myVariable = eyeofcloud?.variableString:("myVariable", userId:"user123", activateExperiment:true, attributes:attributes)
Example Code
Map<String, String> attributes = new HashMap<String, String>(); attributes.put("DEVICE", "iPhone"); attributes.put("AD_SOURCE", "my_campaign"); String userId = "user123"; // Get the value of a Boolean variable Boolean myVariable = eyeofcloudClient.getVariableBoolean("myVariable", userId, true, attitudes); // Get the value of a Boolean variable without sending pageview Boolean myVariable = eyeofcloudClient.getVariableBoolean("myVariable", userId, false, attitudes); // Get the value of a floating point variable Float myVariable = eyeofcloudClient.getVariableFloat("myVariable", userId, true, attitudes); // Get the value of an integer variable Integer myVariable = eyeofcloudClient.getVariableInteger("myVariable", userId, true, attitudes); // Get the value of a string variable String myVariable = eyeofcloudClient.getVariableString("myVariable", userId, true, attitudes);
组
可以使用优化方案组来保持优化方案互斥,并消除交互效应。
作为组的一部分的优化方案在SDK中具有完全相同的接口:像任何其他试验一样可以调用 activate
方法 和 track
方法。SDK将确保同一组中的两个优化方案将不会以同一用户ID被激活。
白名单
可以使用白名单强制分配用户到特定的优化版本中,从而进行QA。
白名单信息包含在数据文件的forcedVariations
内容中。设置白名单后,不需要在代码中做额外的事情;如果设置了白名单,则激活优化方案时将基于白名单强制抽中特定优化版本。白名单的优先级高于受众条件和流量分配。但如果优化方案未激活运行,则白名单不起作用。
匿名IP
在某些国家/地区,需要删除IP地址的最后一个区块,以保护访问者的身份,云眼提供匿名IP功能。
SDK配置
可以为Eyeofcloud实例提供参数,以配置SDK的行为:
- Event dispatcher:配置SDK如何将事件发送到云眼
- Logger:配置SDK在某些事件发生时如何记录消息
- Error handler:配置生产环境中如何处理错误
- User profile:配置SDK需要持久化的用户状态
SDK提供了默认的Event dispatcher、Logger和Error handler实现,但是如果生产应用程序中有不同的要求,建议重写默认的实现。如果只是想对默认实现作出修改,请参阅SDK源代码中的参考实现示例。
Event dispatcher
可以通过提供请求分发方法来更改SDK如何将事件发送到云眼。如果SDK默认的Event dispatcher实现不满足开发需求,可以提供自己的Event dispatcher作为Eyeofcloud实例的参数。
事件调度函数接受具有以下三个属性的事件对象: httpVerb
、url
和params
,这三个参数是实例化EventBuilder
类时需要的。POST
请求应该包含url
与将params
放在body中(请确保格式为JSON),并在header包含{content-type: 'application/json'}
。
Android SDK包含默认的事件调度实现,包含队列和刷新功能,即使APP离线了也可以正常工作。
Objective-C SDK包含默认的事件调度实现EyeofcloudSDKEventDispatcher
,该类包含队列和刷新功能,即使APP离线了该类也可以正常工作。
Swift SDK包含默认的事件调度实现EyeofcloudSDKEventDispatcher
,该类包含队列和刷新功能,即使APP离线了该类也可以正常工作。
Example Code
from .event_dispatcher import EventDispatcher as event_dispatcher // Create an Eyeofcloud client with the default event dispatcher eyeofcloud_client = eyeofcloud.Eyeofcloud(datafile, event_dispatcher=event_dispatcher)
Example Code
import com.eyeofcloud.ab.Eyeofcloud; import com.eyeofcloud.ab.config.parser.ConfigParseException; import com.eyeofcloud.ab.event.AsyncEventHandler; import com.eyeofcloud.ab.event.EventHandler; // Creates an async event handler with a max buffer of // 20,000 events and a single dispatcher thread EventHandler eventHandler = new AsyncEventHandler(20000, 1); Eyeofcloud eyeofcloudClient; try { // Create an Eyeofcloud client with the default event dispatcher eyeofcloudClient = Eyeofcloud.builder(datafile, eventHandler).build(); } catch (ConfigParseException e) { // Handle exception gracefully return; }
Example Code
var defaultEventDispatcher = require('eyeofcloud-client-sdk/lib/plugins/event_dispatcher'); // Create an Eyeofcloud client with the default event dispatcher var eyeofcloudClientInstance = eyeofcloud.createInstance({ datafile: datafile, eventDispatcher: defaultEventDispatcher });
Example Code
EventHandler eventHandler = YourEventHandler.getInstance(); // Create an Eyeofcloud client with your own event handler Eyeofcloud eyeofcloudClient = Eyeofcloud.builder(datafile, eventHandler).build();
Example Code
# Create an Eyeofcloud client with the default event dispatcher eyeofcloud_client = Eyeofcloud::Project.new(datafile, Eyeofcloud::EventDispatcher.new)
Example Code
var defaultEventDispatcher = require('eyeofcloud-server-sdk/lib/plugins/event_dispatcher'); // Create an Eyeofcloud client with the default event dispatcher var eyeofcloudClient = eyeofcloud.createInstance({ datafile: datafile, eventDispatcher: defaultEventDispatcher });
Example Code
var defaultEventDispatcher = require('eyeofcloud-client-sdk/lib/plugins/event_dispatcher'); // Create an Eyeofcloud client with the default event dispatcher var eyeofcloudClientInstance = eyeofcloud.createInstance({ datafile: datafile, eventDispatcher: defaultEventDispatcher });
Example Code
use Eyeofcloud\Event\Dispatcher\DefaultEventDispatcher; // Create an Eyeofcloud client with the default event dispatcher $eyeofcloudClient = new Eyeofcloud($datafile, new DefaultEventDispatcher());
Example Code
CustomEventDispatcher<EOCEventDispatcher> *customEventDispatcher = [[CustomEventDispatcher alloc] init]; // initialize your Manager (settings will propagate to EOCClient and Eyeofcloud) EOCManager *manager = [EOCManager init:^(EOCManagerBuilder * _Nullable builder) { builder.projectId = kProjectId; builder.eventDispatcher = eventDispatcher; }];
Example Code
let customEventDispatcher: CustomEventDispatcher = CustomEventDispatcher.init() // initialize your Manager (settings will propagate to EOCClient and Eyeofcloud) let manager: EOCManager? = EOCManager.init({ (builder) in builder!.datafile = datafile builder!.eventDispatcher = customEventDispatcher })
Logger
在Python SDK中,默认情况下未启用日志记录功能。如果默认的Logger实现不满足开发需求,可以提供自己的Logger实现作为Eyeofcloud实例的参数。
在Ruby SDK中,默认情况下未启用日志记录功能。如果默认的Logger实现不满足开发需求,可以提供自己的Logger实现作为Eyeofcloud实例的参数。
在Node SDK中,默认情况下未启用日志记录功能。如果默认的Logger实现不满足开发需求,可以提供自己的Logger实现作为Eyeofcloud实例的参数。
在Java SDK中,默认情况下未启用日志记录功能。如果默认的Logger实现不满足开发需求,可以提供自己的Logger实现作为Eyeofcloud实例的参数。
EyeofcloudLogLevelInfo
EyeofcloudLogLevelInfo
日志级别在SDK之间可能略有不同:
日志级别 | 描述 |
---|---|
CRITICAL |
记录导致应用崩溃的事件。 |
ERROR |
记录导致激活和运行优化方案失败的错误事件。 |
(例如,无效的数据文件、无效的优化方案名称等) | |
用户可以采取行动纠正。 | |
WARNING |
记录可能导致激活和运行优化方案失败的事件。 |
(例如,调用已被弃用的API、getter方法返回nil等) | |
DEBUG |
记录任何可能跟错误有关的信息,以帮助进行调试。 |
INFO |
记录常规事件(例如,开始激活优化方案、激活成功等)。 |
这有助于显示API调用的生命周期。 |
Example Code
from .logger import NoOpLogger as logger eyeofcloud_client = eyeofcloud.Eyeofcloud(datafile, event_dispatcher=event_dispatcher, logger=logger)
Example Code
eyeofcloud_client = Eyeofcloud::Project.new(datafile, Eyeofcloud::EventDispatcher.new, Eyeofcloud::NoOpLogger.new)
Example Code
var defaultLogger = require('eyeofcloud-server-sdk/lib/plugins/logger'); var eyeofcloudClient = eyeofcloud.createInstance({ datafile: datafile, eventDispatcher: defaultEventDispatcher, logger: defaultLogger.createLogger(), });
Example Code
var defaultLogger = { log: function(message) { console.log(message); }, }; // custom logger var eyeofcloudClientInstance = eyeofcloud.createInstance({ datafile: datafile, eventDispatcher: defaultEventDispatcher, logger: defaultLogger, }); // custom logLevel (2, DEBUG) with default logger var eyeofcloudClientInstance = eyeofcloud.createInstance({ datafile: datafile, logLevel: 2, });
Example Code
use Eyeofcloud\Logger\DefaultLogger; $eyeofcloudClient = new Eyeofcloud($datafile, null, new DefaultLogger());
Example Code
var defaultLogger = { log: function(message) { console.log(message); }, }; // custom logger var eyeofcloudClientInstance = eyeofcloud.createInstance({ datafile: datafile, eventDispatcher: defaultEventDispatcher, logger: defaultLogger, }); // custom logLevel (2, DEBUG) with default logger var eyeofcloudClientInstance = eyeofcloud.createInstance({ datafile: datafile, logLevel: 2, });
Example Code
CustomLogger *customLogger = [[CustomLogger alloc] init]; EOCManager *manager = [EOCManager init:^(EOCManagerBuilder * _Nullable builder) { builder.projectId = kProjectId; builder.logger = customLogger; }]; EOCLoggerDefault *eocLogger = [[EOCLoggerDefault alloc] initWithLogLevel:EyeofcloudLogLevelAll]; EOCManager *manager = [EOCManager init:^(EOCManagerBuilder * _Nullable builder) { builder.projectId = kProjectId; builder.logger = eocLogger; }];
Example Code
let customLogger: CustomLogger? = CustomLogger() let manager: EOCManager? = EOCManager.init({ (builder) in builder!.projectId = projectId builder!.logger = customLogger }) let eocLogger: EOCLoggerDefault? = EOCLoggerDefault.init(logLevel: EyeofcloudLogLevel.All) let manager: EOCManager? = EOCManager.init({ (builder) in builder!.projectId = projectId builder!.logger = eocLogger })
Example Code
# android-logger.properties example # Core logger.com.eyeofcloud.ab.Eyeofcloud=DEBUG:Optly.core logger.com.eyeofcloud.ab.annotations=DEBUG:Optly.annotations logger.com.eyeofcloud.ab.bucketing=DEBUG:Optly.bucketing logger.com.eyeofcloud.ab.config=DEBUG:Optly.config logger.com.eyeofcloud.ab.error=DEBUG:Optly.error logger.com.eyeofcloud.ab.event=DEBUG:Optly.event logger.com.eyeofcloud.ab.internal=DEBUG:Optly.internal # Android logger.com.eyeofcloud.ab.android.sdk=DEBUG:Optly.androidSdk logger.com.eyeofcloud.ab.android.event_handler=DEBUG:Optly.eventHandler logger.com.eyeofcloud.ab.android.shared=DEBUG:Optly.shared logger.com.eyeofcloud.ab.android.user_profile=DEBUG:Optly.userProfile # Disable most SDK logs by commenting all other lines and uncommenting below #logger.com.eyeofcloud.ab=ASSERT:Optly
Error handler
可以提供自定义的错误处理程序逻辑,以便在整个生产环境中进行标准化。在以下情况下将调用此错误处理程序:
- 未知的优化方案名称被引用
- 未知的事件名称被引用
如果错误处理程序未被重写,默认情况下将使用无操作错误处理程序。
Example Code
from .error_handler import NoOpErrorHandler as error_handler eyeofcloud_client = eyeofcloud.Eyeofcloud(datafile, event_dispatcher=event_dispatcher, logger=logger, error_handler=error_handler)
Example Code
import com.eyeofcloud.ab.Eyeofcloud; import com.eyeofcloud.ab.error.ErrorHandler; import com.eyeofcloud.ab.error.RaiseExceptionErrorHandler; import com.eyeofcloud.ab.event.AsyncEventHandler; import com.eyeofcloud.ab.event.EventHandler; EventHandler eventHandler = new AsyncEventHandler(20000, 1); // Default handler that raises exceptions ErrorHandler errorHandler = new RaiseExceptionErrorHandler(); Eyeofcloud eyeofcloudClient; try { // Create an Eyeofcloud client with the default event dispatcher eyeofcloudClient = Eyeofcloud.builder(datafile, eventHandler). .withErrorHandler(errorHandler) .build(); } catch (ConfigParseException e) { // Handle exception gracefully return; }
Example Code
// Event handler is required to make Eyeofcloud EventHandler eventHandler = YourEventHandler.getInstance(); // You can optionally provide an error handler ErrorHandler errorHandler = YourErrorHandler.getInstance(); Eyeofcloud eyeofcloudClient = Eyeofcloud.builder(datafile, eventHandler) .withErrorHandler(errorHandler) .build();
Example Code
eyeofcloud_client = Eyeofcloud::Project.new(datafile, Eyeofcloud::EventDispatcher.new, Eyeofcloud::NoOpLogger.new, Eyeofcloud::NoOpErrorHandler.new)
Example Code
var defaultErrorHandler = require('eyeofcloud-server-sdk/lib/plugins/error_handler'); eyeofcloudClient = eyeofcloud.createInstance({ datafile: datafile, errorHandler: defaultErrorHandler, eventDispatcher: defaultEventDispatcher, logger: defaultLogger.createLogger(), });
Example Code
var defaultErrorHandler = require('eyeofcloud-server-sdk/lib/plugins/error_handler'); var eyeofcloudClientInstance = eyeofcloud.createInstance({ datafile: datafile, errorHandler: defaultErrorHandler, eventDispatcher: defaultEventDispatcher, logger: defaultLogger.createLogger(), });
Example Code
var defaultErrorHandler = require('eyeofcloud-server-sdk/lib/plugins/error_handler'); var eyeofcloudClientInstance = eyeofcloud.createInstance({ datafile: datafile, errorHandler: defaultErrorHandler, eventDispatcher: defaultEventDispatcher, logger: defaultLogger.createLogger(), });
Example Code
use Eyeofcloud\ErrorHandler\DefaultErrorHandler; $eyeofcloudClient = new Eyeofcloud($datafile, null, null, new DefaultErrorHandler());
Example Code
CustomErrorHandler *customErrorHandler = [[CustomErrorHandler alloc] init]; EOCManager *manager = [EOCManager init:^(EOCManagerBuilder * _Nullable builder) { builder.projectId = kProjectId; builder.errorHandler = customErrorHandler; }];
Example Code
let customErrorHandler: CustomErrorHandler? = CustomErrorHandler() let manager: EOCManager? = EOCManager.init({ (builder) in builder!.projectId = projectId builder!.errorHandler = customErrorHandler })
User profile
UserProfile
类在本地数据图表中持久化用户的信息。右边的示例代码示范了在初始化Eyeofcloud实例时如何指定自定义的UserProfile。
默认的UserProfile实现为AndroidSDKUserProfile类,该类记录了SDK根据用户ID激活优化方案和抽取优化版本的历史。比如SDK在后续的会话中,不论优化方案的状态是否发生变化,都将依据UserProfile来激活优化方案和抽选优化版本,即在后续的会话中,用户总会看到相同的优化方案和优化版本。
EOCUserProfile
接口包含以下方法:
- saver: 将
userId
、experimentId
和variationId
的信息存储到设备上。 - lookup: 根据
userId
和experimentId
获取variationId
。 - remove: 根据
userId
和experimentId
将已存储的信息删除。
EOCUserProfile
类在本地数据图表中持久化用户的信息。右边的示例代码示范了在初始化Eyeofcloud实例时如何指定自定义的UserProfile。
默认的EOCUserProfile实现为EyeofcloudSDKUserProfile类,该类记录了SDK根据用户ID激活优化方案和抽取优化版本的历史。比如SDK在后续的会话中,不论优化方案的状态是否发生变化,都将依据UserProfile来激活优化方案和抽选优化版本,即在后续的会话中,用户总会看到相同的优化方案和优化版本。
EOCUserProfile
接口包含以下方法:
- saveUser: 将
userId
、experimentId
和variationId
的信息存储到设备上。 - getVariationForUser: 根据
userId
和experimentId
获取variationId
。 - removeUser: 根据
userId
和experimentId
将已存储的信息删除。
EOCUserProfile
类在本地数据图表中持久化用户的信息。右边的示例代码示范了在初始化Eyeofcloud实例时如何指定自定义的UserProfile。
默认的EOCUserProfile实现为EyeofcloudSDKUserProfile类,该类记录了SDK根据用户ID激活优化方案和抽取优化版本的历史。比如SDK在后续的会话中,不论优化方案的状态是否发生变化,都将依据UserProfile来激活优化方案和抽选优化版本,即在后续的会话中,用户总会看到相同的优化方案和优化版本。
EOCUserProfile
接口包含以下方法:
- saveUser: 将
userId
、experimentId
和variationId
的信息存储到设备上。 - getVariationForUser: 根据
userId
和experimentId
获取variationId
。 - removeUser: 根据
userId
和experimentId
将已存储的信息删除。
Example Code
// Event handler is required to make Eyeofcloud EventHandler eventHandler = YourEventHandler.getInstance(); // You can optionally provide a user profile UserProfile userProfile = UserProfile.getInstance(); Eyeofcloud eyeofcloudClient = Eyeofcloud.builder(datafile, eventHandler) .withUserProfile(userProfile) .build();
Example Code
CustomUserProfile<EOCUserProfile> *customUserProfile = [[CustomUserProfile alloc] init]; // initialize your Manager (settings will propagate to EOCClient and Eyeofcloud) EOCManager *manager = [EOCManager init:^(EOCManagerBuilder * _Nullable builder) { builder.projectId = kProjectId; builder.userProfile = userProfile; }];
Example Code
let customUserProfile: CustomUserProfile? = CustomUserProfile.init() // initialize your Manager (settings will propagate to EOCClient and Eyeofcloud) let manager: EOCManager? = EOCManager.init({ (builder) in builder!.projectId = projectId builder!.userProfile = customUserProfile })
数据文件版本控制
调试
以下是使用SDK进行调试的选项。
设置事件监听
可以设置监听事件来获得各种SDK事件发生的通知。
实例化NotificationListener对象,并根据需求重写相应的回调函数,最后将实例注册到SDK。
以下是可以重写的回调函数:
public void onEventTracked(String eventKey, String userId, Map<String, String> attributes, Long eventValue, LogEvent logEvent)
public void onExperimentActivated(Experiment experiment, String userId, Map<String, String> attributes, Variation varation)
关于iOS的事件监听文档即将推出。
关于iOS的事件监听文档即将推出。
实例化NotificationListener对象,并根据需求重写相应的回调函数,最后将实例注册到SDK。
以下是可以重写的回调函数:
public void onEventTracked(String eventKey, String userId, Map<String, String> attributes, Long eventValue, LogEvent logEvent)
public void onExperimentActivated(Experiment experiment, String userId, Map<String, String> attributes, Variation varation)
Example Code
import com.eyeofcloud.ab.notification.NotificationListener; // Create a new listener and override a method NotificationListener listener = new NotificationListener() { @Override public void onExperimentActivated(Experiment experiment, String userId, Map<String, String> attributes, Variation variation) { Log.i(TAG, "Eyeofcloud experiment activated."); } }; // Add a listener Eyeofcloud eyeofcloudClient = eyeofcloudManager.getEyeofcloud(); eyeofcloudClient.addNotificationListener(listener); // Remove a listener eyeofcloudClient.removeNotificationListener(listener); // Clear all listeners eyeofcloudClient.clearNotificationListeners();
Example Code
import com.eyeofcloud.ab.notification.NotificationListener; // Create a new listener and override methods NotificationListener listener = new NotificationListener() { @Override public void onEventTracked(String eventKey, String userId, Map<String, String> attributes, Long eventValue, LogEvent logEvent) { Log.i(TAG, "Eyeofcloud event tracked."); } @Override public void onExperimentActivated(Experiment experiment, String userId, Map<String, String> attributes, Variation variation) { Log.i(TAG, "Eyeofcloud experiment activated."); } }; // Add a listener Eyeofcloud eyeofcloudClient = eyeofcloudManager.getEyeofcloud(); eyeofcloudClient.addNotificationListener(listener); // Remove a listener eyeofcloudClient.removeNotificationListener(listener); // Clear all listeners eyeofcloudClient.clearNotificationListeners();