开启屏幕方向的自动采集

1.10.1+ 版本 SDK 支持自动采集屏幕方向,可以在初始化 SDK 后调用 enableTrackScreenOrientation: 进行开启,开启后的屏幕方向信息记录在事件的 $screen_orientation 属性中:

[[SensorsAnalyticsSDK sharedInstance] enableTrackScreenOrientation:YES]; 
CODE

开启位置信息自动采集

1.10.1+ 版本 SDK 支持自动采集 GPS 信息,可以在初始化 SDK 后调用 - enableTrackGPSLocation: 方法进行开启,开启后的经纬度信息会乘 10⁶ 后记录在事件的 $longitude$latitude 属性中:

// CoreLocation 采集 GPS 信息
[[SensorsAnalyticsSDK sharedInstance] enableTrackGPSLocation:YES];
CODE

统计事件时长

1.10.6+ 版本 SDK 支持代码埋点来统计事件的时长,只需要在行为开始时调用  - trackTimerStart:,在行为结束时调用 trackTimerEnd:withProperties: 接口,SDK 会自动计算时长,并以秒(浮点数)为单位存在事件的 $event_duration 属性中:

// 开始播放视频时
[[SensorsAnalyticsSDK sharedInstance] trackTimerStart:@"WatchVideo"];

// 暂停播放时
[[SensorsAnalyticsSDK sharedInstance] trackTimerPause:@"WatchVideo"];

// 恢复播放时
[[SensorsAnalyticsSDK sharedInstance] trackTimerResume:@"WatchVideo"];

// 停止或者结束播放时
[[SensorsAnalyticsSDK sharedInstance] trackTimerEnd:@"WatchVideo" withProperties:@{@"VideoType": @"film"}];
CODE

同名事件交叉的时长统计

默认情况下,时长的统计以事件名作为标识,相同的事件名会自动匹配 start-end,如果两个同名事件在时间上有交叉部分,会造成错误匹配。为了解决此问题,1.11.17+ 版本 SDK 支持同名事件交叉的时长统计,开发者需要保存 - trackTimerStart: 的返回值,以便后续针对性地进行暂停、恢复或停止:

// 开始第一个事件计时
NSString *timer1 = [[SensorsAnalyticsSDK sharedInstance] trackTimerStart:@"testTimer"];
 
// 开始第二个事件计时
NSString *timer2 = [[SensorsAnalyticsSDK sharedInstance] trackTimerStart:@"testTimer"];
 
//如果需要暂停第一个事件计时
[[SensorsAnalyticsSDK sharedInstance] trackTimerPause:timer1];
 
//如果需要恢复第一个事件计时
[[SensorsAnalyticsSDK sharedInstance] trackTimerResume:timer1];
 
// 结束第一个事件计时
[[SensorsAnalyticsSDK sharedInstance] trackTimerEnd:timer1];
 
// 结束第二个事件计时
[[SensorsAnalyticsSDK sharedInstance] trackTimerEnd:timer2];
CODE
  • 只有调用 trackTimerEnd: 时,SDK 才会真正记录事件
  • 多次调用 trackTimerStart:,以最后一次调用作为计时起点
  • 默认情况下,统计的时长不包括用户 App 在后台的时长

获取预置属性

前端 SDK 在记录事件时会添加设备相关的预置属性,为了保证前后端事件属性的一致性,某些情况下可能需要在前端获取 SDK 预置属性,1.8.19+ 版本 SDK 可以使用 - getPresetProperties 方法获取事件预置属性,然后通过业务接口传到服务端,由服务端添加到事件属性中:

// 获取事件预置属性
[[SensorsAnalyticsSDK sharedInstance] getPresetProperties];
CODE

事件动态公共属性

动态公共属性和公共属性的区别是:前者适合标记年龄,后者适合标记性别。

对于一些值会变化的公共属性,如当前游戏等级、最新金币余额等,1.10.8+ 版本 SDK 提供了registerDynamicSuperProperties: 接口来设置动态公共属性:

[[SensorsAnalyticsSDK sharedInstance] registerDynamicSuperProperties:^NSDictionary<NSString *,id> * _Nonnull{
	return @{@"level": <#当前游戏等级#>,
			 @"balance": <#最新金币余额#>};
}];
CODE
  • 事件属性的优先级为:track 事件时传入的属性 > 动态公共属性 > 公共属性> 预置属性
  • 动态公共属性的约束和事件属性相同,详情参考数据格式

获取用户 ID

神策中每个事件都会关联到一个 ID 上,用于标识该事件所对应的用户或设备信息,我们称之为 distinct_id,您也可以通过distinctId 接口获取该 ID:

// 获取事件的 ID 标识
[[SensorsAnalyticsSDK sharedInstance] distinctId];
CODE

默认情况下,用户登录前,distinct_id 是 SDK 根据设备生成的一个匿名 ID,一般为IDFA、IDFV 或 UUID。

您也可以通过anonymousId 接口获取当前的匿名 ID:

// 获取匿名 ID
[[SensorsAnalyticsSDK sharedInstance] anonymousId];
CODE

用户属性设置

保留初次属性

对于需要保证只有首次设置时有效的属性,如用户首次充值金额、首次设置的昵称等,可以使用 - setOnce:- setOnce:to: 接口进行记录。与 - set: 方法不同的是,如果被设置的用户属性已存在,则这条记录会被忽略而不会覆盖已有数据,如果属性不存在则会自动创建:

// 设定用户 AdSource 渠道为为 "App Store"
[[SensorsAnalyticsSDK sharedInstance] setOnce:@"AdSource" to:@"App Store"];

// 再次设定用户 AdSource 渠道,设定无效,AdSource 属性值仍然是 "App Store"
[[SensorsAnalyticsSDK sharedInstance] setOnce:@"AdSource" to:@"Email"];
CODE

数值属性累加

针对一些数值型属性,如消费总额、用户积分等属性,我们可以使用 - increment:- increment:by: 对原值进行累加,神策会自动计算并保存累加之后的值:

// 将用户游戏次数属性增加一次
// increment:by: 对一个属性进行累加
[[SensorsAnalyticsSDK sharedInstance] increment:@"GamePlayed" by:[NSNumber numberWithInt:1]];

// 增加用户付费次数和积分
// increment: 对一个或多个属性进行累加
[[SensorsAnalyticsSDK sharedInstance] increment:@{@"UserPaid" : [NSNumber numberWithInt:1],
												  @"PointEarned" : [NSNumber numberWithFloat:12.5]}];
CODE

列表属性追加

对于列表类型用户属性,如用户喜爱的电影、用户点评过的餐厅等属性,可以调用 - append:by: 接口进行追加一些新值:

// 设定用户观影列表属性,设定后属性 "Movies" 为: ["Sicario", @"Love Letter"]
[[SensorsAnalyticsSDK sharedInstance] append:@"Movies" by:[NSSet setWithArray:@[@"Sicario", @"Love Letter"]]];

// 再次设定该属性,属性 "Movies" 为: ["Sicario", @"Love Letter", @"Dead Poets Society"]
[[SensorsAnalyticsSDK sharedInstance] append:@"Movies" by:[NSSet setWithArray:@[@"Love Letter", @"Dead Poets Society"]]];
CODE

列表型属性中的元素必须为 NSString 类型,且元素的值会自动去重。关于列表型限制请见数据格式

属性取消

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

// 取消设置 gender 属性
[[SensorsAnalyticsSDK sharedInstance] unset:@"Gender"];
CODE

开启点击分析功能

版本要求

  • 神策分析 1.13+
  • 此功能依赖于全埋点中点击事件采集的开启
  • 使用此功能前,确保您的 App 中配置了当前项目的 Scheme,详细操作可参考配置 Scheme

1.9.3+ 版本 SDK 支持 App 点击分析功能,SDK 初始化前将 SAConfigOptions 实例 enableHeatMap 属性设置为 YES 即可开启 SDK 的点击分析功能:

// 开启点击分析功能
options.enableHeatMap = YES;
CODE

开启 App 点击分析后,该功能默认对所有页面上的点击生效, 如果您只是想部分页面进行热力图,可以通过 addHeatMapViewControllers: 进行配置添加:

[[SensorsAnalyticsSDK sharedInstance] addHeatMapViewControllers:@"HomeViewController", "DiscoverViewController"];
CODE

埋点数据的加密功能

为了加强埋点数据的安全性,神策分析支持对埋点数据进行加密,并以密文的形式对数据进行存储和发送。

本功能需要服务端的配合,可以联系神策客户成功/项目经理协助开通服务端解密功能。

SDK 端开启加密

对于 2.1.0+ 版本 SDK,初始化前将 SAConfigOptions 实例 enableEncrypt 属性设置为 YES 即可开启 SDK 的加密功能:

// 开启 SDK 加密功能
options.enableEncrypt = YES;
CODE

加密密钥的验证

使用此功能前,确保您的 App 中配置了当前项目的 Scheme,详细操作可参考配置 Scheme

在神策分析平台中,进入密钥管理功能,进入路径:「更多」 → 「基本设置」 → 「数据接入」 → 「密钥管理」

点击「密钥管理」按钮进入密钥管理页面

点击对应密钥的二维码图标,用浏览器扫描二维码打开 App 进行密钥验证。

  • 验证一致,则 App 端提示 "密钥验证通过,所选密钥与 App 端密钥相同"
  • 验证不一致:则 App 端提示 “密钥验证不通过,所选密钥与 App 端密钥不相同。所选密钥版本:v1,App 端密钥版本:v2”
  • 如果本地密钥为空:则 App 端提示 “密钥验证不通过,App 端密钥为空”
  • 如果扫码密钥为空:则 App 端提示 “密钥验证不通过,所选密钥无效”

实时查看当前设备事件数据

  • 使用此功能前,确保您的 App 中配置了当前项目的 Scheme,详细操作可参考配置 Scheme
  • 调试模式只对本次启动有效,退出 App 自动失效

电脑端打开神策分析页面,埋点 -> 导入实时查看 -> Debug 数据 -> 设置设备调试模式,使用相机或其他二维码工具扫码屏幕二维码。

扫码打开 App 后,会弹出提示,选择想要切换的调试模式:
开启调试模式(导入数据):打开调试模式,校验数据,并将数据导入到神策分析中。
开启调试模式(不导入数据):打开调试模式,仅校验数据,但不进行数据导入,数据最终不会进入到数据库。

部分页面开启可视化全埋点

可视化全埋点开启后,默认对 App 内全部页面生效,如果只需要部分页面开启可视化全埋点,可以在 SDK 初始化后使用addVisualizedAutoTrackViewControllers: 进行添加:

// 只开启 MainController 的可视化全埋点
[[SensorsAnalyticsSDK sharedInstance] addVisualizedAutoTrackViewControllers:[NSArray arrayWithObject:@"MainController"]];
OBJECTIVE-C

自定义上报策略

为了减少性能和电量损耗,Android SDK 和 iOS SDK 中事件触发后不会立即上报,而是先将事件缓存在本地,然后定时、批量进行上报。

上报条件

iOS SDK 每次触发事件时会检查如下条件,以判断是否向服务器上传数据:
1. 当前网络是否符合 flushNetworkPolicy (默认 3G、4G、5G、WiFi)
2. 与上次发送的时间间隔是否大于 flushInterval (默认 15 秒)
3. 本地缓存的事件条目数是否大于 flushBulkSize (默认 100 条)

只有1、2 或1、3 满足时,SDK 才会进行发送数据。以上参数支持自定义,可以通过修改相应参数值来达到控制事件上报的频率:

SAConfigOptions *options = [[SAConfigOptions alloc] initWithServerURL:@"<#数据接收地址#>" launchOptions:launchOptions];

// 设置触发间隔,默认 15 * 1000 毫秒
options.flushInterval = 10 * 1000;

// 设置触发条数,默认 100 条
options.flushBulkSize = 50;

[SensorsAnalyticsSDK startWithConfigOptions:options];

// 设置上报网络策略,默认 3G、4G、WiFi,注意需要初始化 SDK 之后设置
[[SensorsAnalyticsSDK sharedInstance] setFlushNetworkPolicy:SensorsAnalyticsNetworkTypeALL];
OBJECTIVE-C

强制上报

如果特定事件需要立即上报,可以在事件触发后调用 - flush 接口强制进行上报:

// 立即上报
[[SensorsAnalyticsSDK sharedInstance] flush];
OBJECTIVE-C

退出上报

为了确保数据的及时上报,SDK 会在应用进入后台或退出时强制触发一次事件上报,如不需要,可以将 flushBeforeEnterBackground 设置为 NO 进行关闭:

// 取消退出触发上报数据,默认开启
[[SensorsAnalyticsSDK sharedInstance] setFlushBeforeEnterBackground:NO];
OBJECTIVE-C

缓存上限

如果事件触发后一直不满足上报条件,本地缓存的数据条数会越来越多,当缓存事件量达到 maxCacheSize 时,每次再触新的事件,SDK 会依次丢弃老数据,保留最新的数据。maxCacheSize 默认为 10000 条,支持客户自定义:

// 设置最大缓存量,默认 10000 条
options.maxCacheSize = 20000;
OBJECTIVE-C

清空本地缓存事件

为了适应 GDPR 要求,1.10.8+ 版本 SDK 增加了 - deleteAll 方法用于清空本地缓存的所有事件:

[[SensorsAnalyticsSDK sharedInstance] deleteAll];
CODE

本地证书校验

1.11.5+ 版本 SDK 发送数据时支持本地证书校验,可按照如下步骤进行配置:

  • 服务器生成 SSL 证书,如果不是 .cer 格式,需要使用 OpenSSL 进行格式转换:

openssl x509 -in 你的证书.crt -out 你的证书.cer -outform der
CODE
  • 将证书拖入项目中,选取相应 Target 并选择 Copy items if needed。
  • 配置神策 SDK 证书校验方式:

/*
设置证书校验方式,默认为 SASSLPinningModeNone
*/
SASecurityPolicy *securityPolicy = [SASecurityPolicy policyWithPinningMode:SASSLPinningModePublicKey];

/*
是否允许无效证书(自建证书),默认为 NO ,
如果是需要验证自建证书,需要设置为 YES 。
*/
securityPolicy.allowInvalidCertificates = YES;

/*
是否需要验证域名,默认为 YES ,
如证书的域名与请求的域名不一致,需把该项设置为 NO 。
*/
securityPolicy.validatesDomainName = NO;

/*
配置本地证书路径
*/
securityPolicy.pinnedCertificates = [SASecurityPolicy certificatesInBundle:[NSBundle mainBundle]];

/*
设置证书策略
*/
[[SensorsAnalyticsSDK sharedInstance] setSecurityPolicy:securityPolicy];
CODE

其中,SSLPinningMode 有以下三种模式:

· SASSLPinningModeNone:默认模式,客户端无条件信任服务端返回证书,不做 App 本地证书校验
· SASSLPinningModePublicKey:只验证证书中公钥,不验证证书的有效期等信息
· SASSLPinningModeCertificate:校验本地证书的所有信息

SASSLPinningModeCertificate 模式会校验证书有效期等信息,如果不能保证用户 App 证书始终处于未过期状态,建议使用SASSLPinningModePublicKey 模式。

追踪并进行渠道匹配和回传

1.10.15+ 版本 SDK 支持追踪自定义事件时进行渠道匹配,可以调用 trackChannelEvent:properties: 对待匹配的事件进行追踪,后台匹配到渠道信息后会将结果回传到渠道商。

 比如用户首次下单时,将下单线索同渠道商进行匹配:

// 用户下单时
[[SensorsAnalyticsSDK sharedInstance] trackChannelEvent:@"PayOrder" properties:@{@"Amount": @(35.0)}];
CODE
  • 当次安装首次触发回传事件,记录事件并进行渠道匹配和回传。
  • 当次安装再次触发回传事件,记录事件,但不进行渠道匹配和回传。
  • 卸载重装首次触发回传事件,记录事件并进行渠道匹配和回传。

p.s. 上述规则适用于同名事件,不同事件之间不相互影响。

App 被动启动($AppStartPassively) 事件说明

对于 iOS 设备,除了用户主动启动 App。设备中某些条件触发时(如收到通知、用户位置信息变化等),系统可能会唤醒 App,使程序在后台运行,当程序在后台启动并运行时,SDK 触发 $AppStartPassively(App 被动启动) 事件。
关于 iOS 设备后台启动和运行的更多信息,可参考 Apple 文档 About the Background Execution Sequence

开启 Crash 信息的自动采集

1.8.12+ 版本 SDK 支持自动采集 Crash 信息,可以在初始化 SDK 时通过配置 SAConfigOptions 进行开启。开启后的 Crash 堆栈信息会记录在 AppCrashed 事件的 app_crashed_reason 属性中:

SAConfigOptions *options = [[SAConfigOptions alloc] initWithServerURL:SA_SERVER_URL launchOptions:launchOptions];
options.enableTrackAppCrash = YES;
[SensorsAnalyticsSDK startWithConfigOptions:options];
CODE

入库前修改事件信息

1.11.16+ 版本 SDK 支持在事件入库前进行修改属性、删除事件,可以使用 - trackEventCallback: 中 block 参数进行设置:

  1. block 中 eventName 参数为当前事件名。
  2. block 中 properties 参数为当前事件属性,该参数为 NSMutableDictionary 类型,可直接修改此参数达到修改事件属性的目的。
  3. block 返回值标志事件是否需要继续入库和上报: YES 事件会继续入库,NO 将删除此条事件。

警告

  • 严禁在 block 中调用 - track:- trackInstallation: - login:  等触发事件的接口,会因循环调用而导致应用崩溃
  • block 返回 NO 时 SDK 将删除此条事件,所以请确保判断逻辑,以免造成误删除事件
[[SensorsAnalyticsSDK sharedInstance] trackEventCallback:^BOOL(NSString *eventName,
                                                               NSMutableDictionary<NSString *,id> *properties) {
    // BuyProduct 事件不进行入库
    if ([eventName isEqualToString:@"BuyProduct"]) {
        return NO;
    }
    
    // 删除 ViewProduct 事件 category 属性
    if ([eventName isEqualToString:@"ViewProduct"]) {
        [properties removeObjectForKey:@"category"];
    }
        
    return YES;
}];
CODE

自定义匿名 ID

默认情况下,SDK 会生成匿名 ID 并可以保证该 ID 的唯一性,如果需要替换神策默认分配的匿名 ID ,可以在初始化 SDK 之后立即调用 identify: 方法进行替换。
代码示例:

[[SensorsAnalyticsSDK sharedInstance] identify:<#自定义匿名 ID#>];
CODE

预编译宏配置 SDK 特性

为了满足客户特殊场景下的需求,SDK 支持通过预编译宏来选择性编译某些功能。通过 CocoaPods 集成时,可以通过添加 subspecs 进行配置;其他集成方式,可以在项目中配置 Preprocessor Macros

功能subspec (CocoaPods 方式)Preprocessor Macros (其他集成方式)备注
禁用 UIWebViewDISABLE_UIWEBVIEWSENSORS_ANALYTICS_DISABLE_UIWEBVIEW=1
卸载重装重新触发激活事件DISABLE_INSTALLATION_MARK_IN_KEYCHAINSENSORS_ANALYTICS_DISABLE_INSTALLATION_MARK_IN_KEYCHAIN=1
屏蔽 GPS 相关代码DISABLE_TRACK_GPSSENSORS_ANALYTICS_DISABLE_TRACK_GPS=1
不采集 UITableView 点击事件DISABLE_AUTOTRACK_UITABLEVIEWSENSORS_ANALYTICS_DISABLE_AUTOTRACK_UITABLEVIEW=1

CocoaPods 集成方式配置

# 添加单个 subspec 
pod 'SensorsAnalyticsSDK', :subspecs => ['DISABLE_UIWEBVIEW']

# 添加多个 subspec 
pod 'SensorsAnalyticsSDK', :subspecs => ['DISABLE_UIWEBVIEW', 'DISABLE_TRACK_GPS']
CODE

其他集成方式配置


查看应用的 App ID Prefix

登录苹果开发者网站,在 Certificates, Identifiers & Profiles 页面,查看对应的 App ID Prefix