为了优化接入体验,请使用新版接入文档,本文档将不再维护~

快速接入

约 5893 字大约 20 分钟

本文档为iOS接入 引力引擎open in new window 的技术接入方案,我们会在本文档中为您详细讲解 iOS SDK 接入过程中的要点。

提示

在接入前, 请先阅读 接入前准备

注意

在正式上线之前,请参考 接入验证 完成接入校验。

1. 集成引力引擎 SDK

1.1 CocoaPods 自动集成

1.创建并编辑 Podfile 内容(如果已有,直接编辑):

创建 Podfile,项目工程(.xcodeproj)文件同目录下命令行执行命令:

pod init

编辑 Podfile 的内容如下:

platform :ios, '9.0'
target 'YourProjectTarget' do
  pod 'GravityEngineSDK'
end

2.执行安装命令

pod install

3.导入成功,启动工程

命令执行成功后,会生成 .xcworkspace 文件,说明您已成功导入 iOS SDK。打开 .xcworkspace 文件以启动工程(注意:此时不能同时开启 .xcodeproj 文件)

1.2 手动集成 SDK

  1. 下载并解压 最新 iOS SDKopen in new window

  2. 将 GravityEngineSDK.xcframework 拖入 XCode Project Workspace 工程项目中

  3. 找到 Targets,在 Build Settings 菜单的 Other linker flags 选项添加 -ObjC

  4. 切换到 Build Phases 选项卡,在 Link Binary With Libraries 栏目下添加如下依赖项:

    1. libz.tbd
    2. Security.framework
    3. AdServices.framework(optional 形式引入)
    4. SystemConfiguration.framework
    5. libsqlite3.tbd
    6. AppTrackingTransparency.framework(获取 idfa 需要)
    7. AdSupport.framework(获取 idfa 需要)

    警告

    以上依赖项,必须全部添加,否则会导致编译失败!

2. 配置并启动 SDK

GEConfig *config = [GEConfig new];
config.appid = "APP_ID";
config.accessToken = "ACCESS_TOKEN";
config.debugMode = GravityEngineDebugOn;
[GravityEngineSDK startWithConfig:config];
GravityEngineSDK *instance = [GravityEngineSDK sharedInstanceWithAppid:config.appid];

// 开启自动采集
[instance enableAutoTrack:GravityEngineEventTypeAll];

参数说明:

注意

应用每次启动都要执行 SDK 的启动逻辑,建议在用户同意隐私政策弹窗之后尽早调用。

警告

请一定注意,要按照文档要求,开启自动采集,否则可能会导致买量问题!

3. 常用功能

3.1 初始化

建议在用户同意网络授权弹窗,然后同意隐私协议弹窗并向用户展示过 App Tracking Transparency(ATT)许可弹窗open in new window 弹窗之后,无论用户是否允许 ATT 追踪,都要执行引力的初始化逻辑。具体接入步骤如下:

3.1.1 先尝试获取 idfa

  1. 先导入框架
    #import <AdSupport/ASIdentifierManager.h>
    
  2. 获取广告标识
    // iOS14以下版本继续使用老方法
    // 判断在设置-隐私里用户是否打开了广告跟踪
    if ([[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]) {
       NSString *idfa = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];
       NSLog(@"%@",idfa);
    } else {
       NSLog(@"用户未在设置-隐私中开启广告追踪,无法获取idfa");
    }
    

3.1.2 再调用引力初始化

[instance initializeGravityEngineWithAsaEnable:ENABLE_ASA withClientId:USER_CLIENT_ID withCaid1:USER_CAID1_MD5 withCaid2:USER_CAID2_MD5 withSyncAttribution:ENABLE_SYNC_ATTRIBUTION withChannel:CHANNEL withSuccessCallback:^(NSDictionary * _Nonnull response) {
   NSLog(@"gravity engine initialize success, response is %@", response);
} withErrorCallback:^(NSError * _Nonnull error) {
   NSLog(@"gravity engine initialize failed, and error is %@", error);
}];

参数说明:

  • ENABLE_ASA : 是否开启 ASA 广告归因,传 YES 则开启,引力会自动获取 ASA 归因信息,传 NO 则引力不会获取。
  • USER_CLIENT_ID : 当前用户在引力系统中的唯一标识,如果传空字符串,则引力 sdk 内部会采集一个稳定的 idfv 作为用户唯一标识(推荐传空字符串)
  • USER_CAID1_MD5 : 当前用户中广协 ID 的 md5 hash(20230330 版本)(可为空字符串)
  • USER_CAID2_MD5 : 当前用户中广协 ID 的 md5 hash(20220111 版本,在 2025 年 6 月 30 日后,需要传入 20250325 版本)(可为空字符串)
  • ENABLE_SYNC_ATTRIBUTION : 是否开启同步获取归因信息,具体请参考同步归因
  • CHANNEL : 当前用户渠道,您可以自行定义传入的参数,如无自定义的需求,可以传入默认值:appstore

注意

接中广协通知:预计 2025 年 6 月 30 日起,中广协平台下发的 CAID 将新增20250325版本,并下线20220111版本。

目前引力后端已经支持轮转升级,您需要在 2025 年 6 月 30 日后,做如下调整:

  • 确保获取中广协20230330版本的 CAID,并在客户端初始化引力引擎 sdk 时,传递给 USER_CAID1_MD5 参数
  • 获取中广协20250325版本的 CAID,并在客户端初始化引力引擎 sdk 时,传递给 USER_CAID2_MD5 参数

CAID 只要有一个版本正确匹配,即可正常归因,所以严格按照上述条件来传递参数,则不会影响基于 CAID 的归因判定!

注意

  • 首次调用后,需要等 CallbackWithSuccess 回调成功之后,才能继续调用后续的事件上报方法
  • 调用成功之后,后续冷启动可以不再调用初始化,只需要正常启动 SDK 即可(多次调用也不会有问题,引力做了兼容)
  • 以上字符串参数无值时,请传入空字符串,不要传入nil

警告

注意:请确保用户已经同意网络授权弹窗之后,才能调用引力初始化接口,如果提前调用,将因为网络不通导致初始化失败!导致首次启动归因失败!

3.1.3 最佳实践(推荐)

兼容 iOS14 系统之前和 iOS14 系统之后获取 idfa 的代码,并在无论是否获取到 idfa 时,都调用引力 SDK 的 initialize 函数。我们推荐您 withClientId 传入空字符串,这样引力将在 sdk 内部自动为您处理clientId 的采集逻辑。

// 先获取idfa
if (@available(iOS 14, *)) {
   // iOS14及以上版本需要先请求权限(依赖ATT框架)
   [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
      // 获取到权限后,使用老方法获取idfa
      if (status == ATTrackingManagerAuthorizationStatusAuthorized) {
            NSString *idfa = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];
            NSLog(@"%@",idfa);
      } else {
            NSLog(@"当前用户未同意追踪或未在设置-隐私中开启广告追踪,无法获取idfa");
      }
      //无论是否获取到idfa 都要调用引力SDK initialize函数,SDK内部会尝试获取idfa,并处理idfa异常值
      [instance initializeGravityEngineWithAsaEnable:ENABLE_ASA withClientId:@"" withCaid1:USER_CAID1_MD5 withCaid2:USER_CAID2_MD5 withSyncAttribution:ENABLE_SYNC_ATTRIBUTION withChannel:CHANNEL withSuccessCallback:^(NSDictionary * _Nonnull response) {
         NSLog(@"gravity engine initialize success, response is %@", response);
      } withErrorCallback:^(NSError * _Nonnull error) {
         NSLog(@"gravity engine initialize failed, and error is %@", error);
      }];
   }];
} else {
   // iOS14以下版本继续使用老方法
   // 判断在设置-隐私里用户是否打开了广告跟踪
   if ([[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]) {
      NSString *idfa = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];
      NSLog(@"%@",idfa);
   } else {
      NSLog(@"用户未在设置-隐私中开启广告追踪,无法获取idfa");
   }
   //无论是否获取到idfa 都要调用引力SDK initialize函数,SDK内部会尝试获取idfa,并处理idfa异常值
   [instance initializeGravityEngineWithAsaEnable:ENABLE_ASA withClientId:@"" withCaid1:USER_CAID1_MD5 withCaid2:USER_CAID2_MD5 withSyncAttribution:ENABLE_SYNC_ATTRIBUTION withChannel:CHANNEL withSuccessCallback:^(NSDictionary * _Nonnull response) {
      NSLog(@"gravity engine initialize success, response is %@", response);
   } withErrorCallback:^(NSError * _Nonnull error) {
      NSLog(@"gravity engine initialize failed, and error is %@", error);
   }];
}

提示

  • 在混合上报的场景下,如您需要获取当前用户的 clientId,您可以调用 getCurrentClientId 方法获取;
  • 采用最佳实践方案,并且传入的 clientId 字段为空字符串时,引力 sdk 内部会自动获取当前 app 的 version、idfa、idfv,并将首次获取的 idfv 保存到钥匙串中,保证当前设备后续卸载重装之后,能始终获取到最初的 idfv,并将这个稳定的 idfv 作为 client id 传给引力后台作为唯一用户 ID;
  • version 获取的逻辑为:采集 CFBundleVersion 字符串,并将小数点去除转换为 int 类型上报给引力后台,代码如下;
NSString *buildVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];

4. 行为事件上报

4.1 业务注册事件上报(可选)

当用户完成应用内业务注册后,您可以调用 trackRegisterEvent 方法来上报用户注册事件($AppRegister)给引力,引力会使用该事件统计指标:标准_注册数。

[instance trackRegisterEvent];

相关信息

该方法可多次调用,每次调用都会上报一个用户注册事件(计算指标时会去重)。

4.2 付费事件上报

当用户发生付费行为时,需要调用 trackPayEvent 方法记录用户付费事件,此事件非常重要,会影响买量和 ROI 统计,请务必重点测试!

/**
 * 上报付费事件
 * @param payAmount     付费金额 单位为分
 * @param payType       货币类型 按照国际标准组织ISO 4217中规范的3位字母,例如CNY人民币、USD美金等
 * @param orderId       订单号
 * @param payReason     付费原因 例如:购买钻石、办理月卡
 * @param payMethod     付费方式 例如:支付宝、微信、银联等
 */
[instance trackPayEventWithAmount:1000 withPayType:@"CNY" withOrderId:@"order_id_xxx1" withPayReason:@"月卡" withPayMethod:@"支付宝"];

国际标准组织 ISO 4217 代码表open in new window

相关信息

如果您需要通过后端 API 方式上报付费事件,请参考 混合上报模式 来接入事件上报接口报送付费事件。

警告

  • 参数 payAmount 单位为分,请务必注意,传错单位可能会导致买量受到影响!
  • 引力引擎会通过订单号 orderId 去重,避免重复上报,请务必传入!

4.3 广告观看事件上报

若您的产品内有广告变现,则需要在用户点击广告观看的同时上报用户广告观看事件给引力,具体参考如下:

/**
 * 上报广告观看事件 参数如下
 * @param adUnionType   广告聚合平台类型  (取值为:topon、gromore、admore、self,分别对应Topon、Gromore、Admore、自建聚合)
 * @param adPlacementId 广告瀑布流ID(广告位ID)
 * @param adSourceId    广告源ID(代码位ID)
 * @param adType        广告类型 (取值为:reward、banner、 native 、interstitial、 splash ,分别对应激励视频广告、横幅广告、信息流广告、插屏广告、开屏广告)
 * @param adnType       广告平台类型(取值为:csj、gdt、ks、 mint 、baidu,分别对应为穿山甲、优量汇、快手联盟、Mintegral、百度联盟)
 * @param ecpm          预估ECPM价格(千次展示收入(单位元))
 */
[instance trackAdShowEventWithUninType:@"topon" withPlacementId:@"placement_id" withSourceId:@"ad_source_id" withAdType:@"reward" withAdnType:@"csj" withEcpm:@1000];

警告

参数 ecpm 单位为元,请务必注意,做好单位转换,传错单位可能会导致买量受到影响!

4.4 提现事件上报(可选)

当用户发生应用内提现行为时,需要调用 trackWithdrawEvent 方法记录用户提现事件!

/**
 * 上报付费事件
 * @param payAmount     付费金额 单位为分
 * @param payType       货币类型 按照国际标准组织ISO 4217中规范的3位字母,例如CNY人民币、USD美金等
 * @param orderId       订单号
 * @param payReason     付费原因 例如:购买钻石、办理月卡
 * @param payMethod     付费方式 例如:支付宝、微信、银联等
 */
[instance trackWithdrawEventWithAmount:@1000 withPayType:@"CNY" withOrderId:@"order_id_xxx1" withPayReason:@"用户首次提现" withPayMethod:@"支付宝"];

国际标准组织 ISO 4217 代码表open in new window

4.5 设置公共事件属性

对于一些重要的属性,譬如玩家的区服和渠道等,这些属性需要设置在每个事件中,此时您可以将这些属性设置为公共事件属性。公共事件属性指的就是每个事件都会带有的属性,您可以调用 setSuperProperties 来设置公共事件属性,我们推荐您在发送事件前,先设置公共事件属性。

NSMutableDictionary *superProperties = [NSMutableDictionary new];
[superProperties setValue:@"ta" forKey:@"channel"];//字符串
[superProperties setValue:@1 forKey:@"age"];//数字
[superProperties setValue:@YES forKey:@"isSuccess"];//布尔
[superProperties setValue:[NSDate now] forKey:@"birthday"];//时间
[superProperties setValue:@[@{@"key":@"value"}] forKey:@"object_arr"];//对象组
[superProperties setValue:@[@"value"] forKey:@"arr"];//数组

[instance setSuperProperties:superProperties];//设置公共事件属性

公共事件属性将会被保存到缓存中,无需每次启动 APP 时调用。如果调用 setSuperProperties 上传了先前已设置过的公共事件属性,则会覆盖之前的属性。如果公共事件属性和 track() 上传的某个属性的 Key 重复,则该事件的属性会覆盖公共事件属性。

  • 事件的属性是一个 NSDictionary 对象,其中每个元素代表一个属性。
  • Key 为该属性的名称,为字符串类型,规定只能以字母开头,包含数字,字母和下划线 "_",长度最大为 50 个字符。
  • Value 为该属性的值,支持字符串、数字、布尔、时间、对象组、数组。
  • 如果您需要上传布尔型的属性,则请以 @YES 与 @NO 或 [NSNumber numberWithBool:YES] 与 [NSNumber numberWithBool:NO] 来赋值。不可以使用 @true、 @false、 @TRUE 和 @FALSE 赋值布尔型数据。
  • 如果您需要删除某个公共事件属性,可以调用 unsetSuperProperty 清除其中一个公共事件属性;
  • 如果您想要清空所有公共事件属性,则可以调用 clearSuperProperties;

注意

公共属性需要先在事件属性open in new window中添加,否则会上报失败!

4.6 记录事件时长

如果您需要记录某个事件持续时长,您可以调用 timeEvent 来开始计时,配置您想要计时的事件名称,当您上传该事件时,将会自动在您的事件属性中加入 $event_duration 这一属性来表示记录的时长,单位为秒。

//以下示例,完成用户在某个商品页面停留时长的统计
[instance timeEvent:@"stay_shop"];
 /**do someting
    .......
 **/
//用户离开商品页面,计时结束,"stay_shop" 这一事件中将会带有表示事件时长的属性$event_duration
[instance track:@"stay_shop"];

4.7 立即上报事件

如果需要立即上报缓存的事件,可以调用 flush 来上报所有缓存的事件。

[instance flush];

4.8 上报自定义事件

您可以调用 track 方法,记录用户自定义事件。

建议您先在元事件open in new window中添加自定义事件,然后在游戏中指定位置埋点调用 track 方法上报自定义事件,此处以用户购买某商品作为范例。

NSDictionary *eventProperties = @{ @"product_name": @"商品名"};
[instance track:@"product_buy" properties:eventProperties];

事件名称是字符串类型,只能以字母开头,可包含数字,字母和下划线 “_”,长度最大为 50 个字符。


5. 用户属性上报

目前支持的用户属性设置接口为 user_set、user_set_once、user_increment、user_number_max、user_number_min、user_append、user_uniqAppend、user_unset、user_delete。

5.1 设置用户属性

对于一般的用户属性,您可以调用 user_set 来进行设置,使用该接口上传的属性将会覆盖原有的属性值,如果之前不存在该用户属性,则会新建该用户属性。

// 设置用户属性
//此时"username"为"GravityEngineUser"
[instance user_set:@{@"username": @"GravityEngineUser"}];
//此时"username"为"TestUserName"
[instance user_set:@{@"username": @"TestUserName"}];

5.2 初始化用户属性

对于只在首次设置时有效的属性,我们可以使用 user_set_once 记录这些属性。与 user_set 方法不同的是,如果被设置的用户属性已存在,则这条记录会被忽略而不会覆盖已有数据,如果属性不存在则会自动创建。因此,user_set_once 适用于为用户设置首次激活时间、首次注册时间等属性。例如:

//first_payment_time为2023-01-01 04:43:35.968
[instance user_set_once:@{@"first_payment_time": @"2023-01-01 04:43:35.968"}];
//first_payment_time仍然为2023-01-01 04:43:35.968
[instance user_set_once:@{@"first_payment_time": @"2018-12-31 01:23:45.678"}];

5.3 累加用户属性

对于数值型的用户属性,可以使用 user_increment 对属性值进行累加。常用于记录用户付费次数、付费额度、积分等属性。例如:

//此时$age为30
[instance user_increment:@{@"$age": @30}];

//此时$age为32
[instance user_increment:@{@"$age": @2}];

5.4 用户属性取最大值

对于数值型的用户属性,可以使用 user_number_max 用来比较数值大小,保存较大的,如果没有这个 key,则新增 key,value 取本次的值

//此时$age为30
[instance user_number_max:@{@"$age": @30}];

//此时$age仍为30
[instance user_number_max:@{@"$age": @27}];

5.5 用户属性取最小值

对于数值型的用户属性,可以使用 user_number_min 用来比较数值大小,保存较小的,如果没有这个 key,则新增 key,value 取本次的值

//此时$age为30
[instance user_number_min:@{@"$age": @30}];

//此时$age仍为30
[instance user_number_min:@{@"$age": @100}];

5.6 Array 追加

对用户喜爱的电影、用户点评过的餐厅等属性,可以调用 user_append 记录列表型属性,例如:

// 调用 user_append 为用户属性 Movies 追加元素。如果不存在,会新建该元素
[instance user_append:@{@"Movies": @[@"Interstellar", @"The Negro Motorist Green Book"]}];

5.7 Array 去重追加

调用 user_uniqAppend 用来对 Array 类型的用户数据去重追加元素,例如:

// 调用 user_uniqAppend 为用户属性 Movies 去重追加元素。如果不存在,会新建该元素
[instance user_uniqAppend:@{@"Movies": @[@"Interstellar", @"The Negro Motorist Green Book"]}];

5.8 清空用户属性

调用 user_delete 方法,将把当前用户属性清空,您将无法再查询该名用户的用户属性,但该用户产生的事件仍然可以被查询到

[instance user_delete];

5.9 重置用户属性

如果需要重置已设置的某个用户属性,可以调用 user_unset 进行取消:

// 清空该用户的累计付费金额属性值
[instance user_unset:@"total_pay"];

6. 其他功能

6.1 自动采集事件

引力引擎 SDK 支持自动采集一些基础事件以降低您的接入成本,您可以参考自动采集一文来快速开启。

6.2 开启 Debug 模式

开启 Debug 模式后,当出现问题时会以日志和异常的方式提示用户,您也可以去事件流open in new window中查看实时上报的数据数,辅助您判断数据接入是否正常。

以下是客户端开启 Debug 模式的示例代码:

GEConfig *config = [[GEConfig alloc] init];
config.debugMode = GravityEngineDebugOn;
// 初始化 SDK
GravityEngineSDK *instance = [GravityEngineSDK startWithConfig:config];

警告

Debug 模式仅仅用于集成阶段数据校验,不要在生产模式下使用!

6.3 绑定三方平台

引力支持与其他三方的数据分析平台打通,具体调用如下:

6.3.1 数数

[instance bindTAThirdPlatformWithAccountId:CURRENT_USER_TA_ACCOUNT_ID withDistinctId:CURRENT_USER_TA_DISTINCT_ID];

参数说明:

  • CURRENT_USER_TA_ACCOUNT_ID:当前用户的数数账户 ID (#account_id)
  • CURRENT_USER_TA_DISTINCT_ID:当前用户的数数访客 ID (#distinct_id)

提示

引力会自动将引力 client ID 和您传入的数数 account_id 以及 distinct_id 做关联,在回调数数接口时,通过这个关联传递对应的 account_id、distinct_id 给数数后台

7. 发版记录

版本日期备注
4.2.12023-05-22初始版本上线
4.2.32023-05-28优化初始化、注册、登录、退出登录流程;优化归因参数采集逻辑
4.2.42023-05-31支持 ASA 归因
4.2.52023-06-02性能优化
4.2.62023-06-07修复用户使用时长统计问题
4.2.72023-06-23支持自动采集用户注册事件
4.2.82023-06-29性能优化
4.2.92023-07-05支持 Unity 打通
4.3.12023-07-13支持重置 Client ID;支持打通三方数据平台
4.3.22023-07-14ASA 归因信息自动采集
4.5.12023-08-30支持查询用户信息接口
4.5.22023-09-14支持获取当前 ClientID
4.5.52023-09-20支持同步获取归因结果信息
4.6.12023-10-10性能优化
4.6.22023-11-09支持历史用户注册
4.6.32023-11-28支持补报设备 ID 信息
4.7.22023-12-11接入流程优化,不再自动采集$AppRegister 事件
4.7.32024-02-20性能优化
4.8.32024-04-25提供简化版 initialize 方法
4.8.42024-08-08支持融合归因
4.8.52024-08-12支持客户传入 channel,支持越狱渠道排除
4.8.62024-08-28性能优化
4.8.92025-02-28避免客户误用 login 方法
4.8.102025-03-14性能优化
4.8.112025-04-07报错 catch
5.0.22025-04-23性能优化
5.0.32025-05-24支持初始化时手动传入 clientID