云眼iOS Swift 参数化 AB测试开发指南

本文主要介绍IOS Swift语言如何在云眼平台实施参数化AB测试。

1、参数化API

参数化方案希望的是将应用程序中的一些关键变量动态化,使其不再写死在程序中,而是从一个可变的配置文件中读取对应的值。

在将应用程序参数化前,需要考虑哪些变量是需要参数化的以及哪些目标是有可能使用到的。所有将来可能进行AB测试的关键地方,都建议将其参数化,比如关键按钮(注册、购买等)的一些属性、控制应用行为的一些关键参数、甚至是推荐算法的一些参数等。这样,当将来要进行AB测试的时候就不再需要发布新版本应用了。目标的选择往往是和业务指标相关的一些行为,比如一些按钮的点击,把可能用来衡量结果的目标都考虑进去。

2、确定参数化元素和目标

下面我们以一个简单的swift APP为例:这个APP中包含一段文本描述和一个点击按钮,现在我们提出假设:文本的内容会影响用户的点击率。我们确定需要进行AB测试的就是该APP中文本的内容,衡量结果的指标就是按钮的点击率,所以我们确定需要参数化的元素便是该APP中的文本内容,目标就是APP中按钮的点击率。

确定参数化元素和目标
确定参数化元素和目标

3、创建优化方案

创建优化方案:前往“业务优化”>“创建优化方案”。输入优化方案名称,平台选择“全栈API”,然后点击“确定”完成优化方案的创建。创建完成后页面会自动跳转到编辑器页面。

创建优化方案
创建优化方案

4、添加版本并分配流量

创建优化方案后,进入编辑界面,点击 “添加新版本”按钮可添加新版本,并且可以自行选择参加该实验的流量比例以及为各个版本分配流量。

添加版本并分配流量
添加版本并分配流量

5、设置目标

根据优化方案的设计情况,将需要用到的衡量指标创建为一个目标。输入目标的名称然后点击“创建目标”,目标创建完成后,点击目标后的“+”号将其添加到优化方案中。

设置目标
设置目标

6、设置受众

设置受众可以将优化方案定位到在云眼控制台预先定义的特定受众群体中,云眼将会在激活优化方案时通过属性值评估用户是否满足受众条件,从而决定是否激活优化方案。在云眼控制台中点击“业务优化”,业务优化界面打开后再点击“自定义属性(全栈)”。点击创建自定义属性,输入自定义属性的名称和描述,点击确定按钮。

设置受众-1
设置受众-1

然后在编辑器中点击“创建受众”,输入受众的名称和描述,将右侧已创建好的自定义属性拖拽至受众条件下,然后输入一个属性的值,例如:male,然后点击“保存受众”按钮。(注意:创建的自定义属性的名称和输入的值最终会形成键值对的形式:”Gender”:”male”)。

设置受众-2
设置受众-2

7、启动优化方案

配置完成后点击“启动优化方案”。

启动优化方案
启动优化方案

8、SDK下载与安装

打开云眼控制台,然后点击“业务优化”,业务优化界面打开后点击“SDK下载与安装”。

SDK下载及安装-1
SDK下载及安装-1

在新打开的页面中,选择”IOS SDK安装“,再从下方选择“全栈API SDK安装”,根据下方提示完成SDK安装。

SDK下载与安装-2
SDK下载与安装-2

在添加完云眼SDK之后,在项目中右键新建一个桥接文件Header File,为该文件命名然后点击create。

SDK下载与安装-3
SDK下载与安装-3

创建好桥接文件后,在项目中选择Build Settings,然后找到Swift Compiler – General下的Objective-C Bridging Header,点击该选项,当右侧出现弹框时将刚创建的桥接文件拖入其中。

SDK下载与安装-4
SDK下载与安装-4

然后在桥接文件#endif前引入云眼SDK

#import "EyeofcloudSDKiOS/EyeofcloudSDKiOS.h"

9、SDK初始化

所有和AB测试相关的接口都是定义在EOCClient这个类上的,通过这个类才能够版本抽签、触发目标、获取参数从而进行AB测试。同时,SDK还提供了一个EOCManager类来负责EOCClient的构造和获取、配置文件(包含AB测试信息)的下载和更新、配置文件的缓存管理等等。所以,初始化SDK的第一步就是构造一个EOCManager。建议在Appdelegate上设置一个私有属性保存全局唯一的一个EOCManager,再设计一个getEOCManager的接口将其暴露出来。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
//---- Create eoc Manager ----
   let builder = EOCManagerBuilder{(builder) in
     builder!.projectId = "PROJECT_ID"
}
   eocManager = EOCManager.init(builder : builder) 
   return true
}
func getEOCManager() -> EOCManager? {
        return eocManager
 }

其中参数PROJECT_ID可以从“SDK下载与安装”界面中查到。

获取PROJECT_ID
获取PROJECT_ID

如果您正在使用私有部署的云眼系统,则需要修改配置文件和事件发送的URL。 首先,实例化EOCDatafileManagerDefault类和EOCEventDispatcherDefault类,在各自的初始化方法里设置相应的URL。然后,调用EOCManager的初始化方法,并将以上两个类的实例作为参数传入并赋值给builder 。

// ---- Create the Event Dispatcher ----
    let eventDispatcher = EOCEventDispatcherDefault(builder : EOCEventDispatcherBuilder(block:{(builder) in
      builder?.eventDispatcherEventURL = "事件发送URL"
})) 
// ---- Create the Datafile Manager ----
    let datafileManager = EOCDatafileManagerDefault(builder: EOCDatafileManagerBuilder(block:{(builder) in
      builder!.projectId = "PROJECT_ID"
      builder!.networkServiceCDNServerURL = "配置文件URL"
})) 
//---- Create eoc Manager ----
    let builder = EOCManagerBuilder{(builder) in
      builder?.projectId = "PROJECT_ID"
      builder?.datafileManager = datafileManager!
      builder?.eventDispatcher = eventDispatcher
}
    eocManager = EOCManager.init(builder:builder)

在构造完EOCManager对象后,我们需要调用EOCManager的initialize方法完成EOCClient的初始化。该方法会执行一个异步网络任务去下载配置文件,然后根据配置文件构造一个EOCClient对象并将其保存在eocManager中。在之后需要使用SDK的地方,通过EOCManager的getEyeofcloud方法获取缓存的EOCClient对象再来调用相关接口。本地缓存的配置文件是会自动定时更新的,相应EOCClient对象中配置也会自动更新,因此无需重新调用initialize方法构造新的EOCClient对象。

let eocClient = eocManager?.initialize(callback: {(error:Error?,client:EOCClient?) in
    self.setRootViewController()
})

这里需要注意的一点是,在网络不通的情况下,EOCClient初始化就会失败。例如,首次启动APP时,会触发一个弹框,要求用户设定APP的网络权限。在完成设定之前,APP的网络请求是被禁止的,从而导致EOCClient初始化失败。为了保证AB测试的顺利进行,就要把EOCClient的初始化推迟到APP联网之后。一个简单的办法就是使用AFN监听APP的网络状态,一旦APP联网就开始初始化EOCClient以及加载其它资源,然后重新渲染APP的界面。

在调用SDK的接口时,会需要一个唯一的userId来标识用户。另外,如果要使用受众功能,还会需要用户的属性值。为了方便,可以在Appdelegate中定义两个方法getUserAttributes 和getUserId。

func getUserId() -> String? {
        userId = String(Int(arc4random_uniform(300000)))
        return userId
    } 
 func getUserAttributes() -> [String : String]? {
        userAttributes = [
            "Gender": "female"
        ]
        return userAttributes
}

10、编码实现参数化

我们需要在代码中获取到刚刚创建的变量值然后在程序中去使用,可以通过调用variableString、variationDouble、variationInteger、variationBoolean这四个方法去获取不同类型的变量,然后在需要触发目标事件的地方调用track API,并提供目标名称及用户ID两个参数来跟踪目标事件。

   @IBAction func click(_ sender: Any) {
        self.eocClient?.track("click", userId: appDelegate.getUserId()!)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        self.eocClient = appDelegate.getEOCManager()?.getEyeofcloud()
           let content = self.eocClient?.variableString("text-content",userId:appDelegate.getUserId()!,activateExperiment: true)
           ori.text = content
}

11、简单API中使用参数化API

使用简单API方式可以和参数化API进行配合使用,先调用简单API的activate方法激活一个试验得到版本名称,然后调用参数化API variableString/variableBoolean/variableDouble/variableFloat来获取在云眼控制台定义的变量值,需要提供3个参数,分别是变量名称、用户ID、布尔值true/false,其中最后一个参数的布尔值代表是否激活试验,我们只需要获取变量的值便于使用而并不需要激活试验,所以我们最后一个参数传递false。在这种情况下,我们使用activate API激活试验得到的是哪个版本,则使用参数化API获取到的变量就是我们在云眼控制台定义的该版本的值。例如:我们用activate激活试验返回的是优化版本,则我们使用参数化API获取到的变量值也是优化版本中的变量值。

override func viewDidLoad() {       
super.viewDidLoad()       
self.eocClient = appDelegate.getEOCManager()?.getEyeofcloud()
let variation = self.eocClient?.activate(experimentName,userId:appDelegate.getUserId()!)       
let content = self.eocClient?.variableString("text-content",userId:appDelegate.getUserId()!,activateExperiment: false) 
//根据版本名称在不同的版本下使用获取到的变量值
if variation?.variationKey ==”优化版本#1”{
//Do Something
}else{
//Do something default
}}

12、查看实验结果

当实验运行一段时间后,就可以到云眼控制台查看实验的运行结果。

查看实验结果
查看实验结果

12、示例程序

付费客户需要Demo,请与客户经理联系…

免费AB测试,注册即可开通使用! 立即开通