神策分析 iOS SDK 架构解析

前言

神策分析 iOS SDK,是一款轻量级用于 iOS 端的数据采集埋点 SDK。神策分析 iOS SDK 不仅有代码埋点功能,还通过使用运行时机制(Runtime)中的相关技术实现 iOS 端的全埋点(无埋点、无码埋点、无痕埋点、自动埋点)、点击图、可视化全埋点等功能,下面将以 SDK 版本 v1.11.16 为例介绍神策分析 iOS SDK 的架构。

目录结构

神策分析 iOS SDK 自开源以来,从最开始满足代码埋点的需求,到后来支持全埋点、可视化全埋点,SDK 的代码不断优化,目录结构也不断发生调整。目前开源代码中存在 Example、SensorsAnalyticsSDK 两个工程,Example 是一个测试工程,SensorsAnalyticsSDK 是神策分析 iOS SDK 工程,如下图所示:

Example 工程主要包含了下面几个目录:

  • SensorsData:基于 Objective-C 的 SDK 示例代码
  • SensorsDataSwift:基于 Swift 的 SDK 示例代码
  • SensorsDataExtention:App Extension 的示例代码

SensorsAnalyticsSDK 工程主要包含了下面几个目录:

  • SensorsAnalyticsSDK:神策分析 iOS SDK 的源码
  • SensorsAnalyticsExtension:App Extension 的数据管理类源码
  • SensorsAnalyticsTests:神策分析 iOS SDK 的单元测试源码

数据流程

上一节中对于神策分析 Android SDK 架构解析进行了详细的介绍,为了便于大家进一步理解 SDK 的架构,下面给出数据从采集到上传的流程,如图所示:

架构解析

一、简介

如上所述,神策分析 iOS SDK 是一款轻量级用于 iOS 端的数据采集埋点 SDK。而数据采集是构建数据平台的核心要素,数据采集是否丰富(完整),采集的数据是否准确,采集是否及时,采集的数据能否关联打通,都直接影响整个数据平台的应用效果。因此,神策分析 iOS SDK 采用了高效、可靠的架构来保证数据的采集。

二、架构图

神策分析 iOS SDK 总体架构图如下所示:

下面,我们对 SDK 架构进行详细的解释。

三、架构详解

(一) 配置模块

配置模块主要包括了初始化配置远程配置两个功能,下面分别介绍下这两个功能:

1. 初始化配置

在引入神策分析 iOS SDK 之后,创建初始化配置项 SAConfigOptions,无特殊需求可以直接使用默认配置初始化 SDK。如果用户需要进行配置的更新,可以通过修改 SAConfigOptions 的属性。

配置项 SAConfigOptions 的说明:

  • SAConfigOptions 是个模型类,没有执行额外的逻辑
  • SAConfigOptions 禁用了 – init 和 – new 方法,不允许通过除 – initWithServerURL:launchOptions: 以外的方法初始化对象
  • SAConfigOptions 中某些属性的 set 方法对于数值进行了判断
  • SAConfigOptions 遵守了 NSCopying 协议,可执行 copy 方法来获取一个克隆对象

2. 远程配置

远程配置通过访问对应的数据接收地址下的 config 接口,得到 disableDebugMode、disableSDK 和 autoTrackMode 这三个配置项的值,来控制相应的功能。

(1)初始化 SDK 可配置 SAConfigOptions 中的 disableRandomTimeRequestRemoteConfig 参数,控制是否禁用随机时间请求远程配置,目的是通过设置可分散降低 SDK 远程配置请求的频次。该值的作用如下:为 true,则每次 App 启动后都会访问远程配置接口获取远程配置; 为 false,则会在每次 App 启动时判断是否距离上次请求已超过一个随机时间,超过了则会发送请求,并记录当次的请求时间。

可以通过以下两个子参数来控制随机时间的上下限:
远程配置请求最小间隔时长 minRequestHourInterval(单位为小时,默认值 24 );远程配置请求最大间隔时长 maxRequestHourInterval(单位为小时,默认值 48 )。

(2)App 启动后,SDK 会根据上面设定的规则判断是否满足请求远程配置条件,满足条件则触发远程配置请求。然后根据请求结果作出以下处理:若请求失败,则会自动重试最多 3 次;若请求成功,则更新配置并令之生效。

(3)具体时间约束规则参考 iOS SDK 源码 SensorsAnalyticsSDK.m 类 shouldRequestRemoteConfig 方法。

远程配置请求流程如下图所示:

下面分别介绍下这三个配置项的取值含义

(1)disableDebugMode

  • true:关闭 debugMode
  • false:不做处理
  • 默认值为 false

(2)disableSDK

  • true:关闭 SDK
  • false:开启 SDK
  • 默认值为 false

(3) autoTrackMode

  • -1:不做任何处理
  • 0:关闭全埋点的所有事件
  • 默认值为 -1

这里需要注意的是,如果要开启全埋点中的部分事件,需要用全埋点事件对应的枚举值进行组合。我们先来看下全埋点事件对应的枚举值:

图 点击放大,查看更清晰

从代码中可以知道,全埋点事件对应的十进制枚举值分别为:

  • $AppStart:1
  • $AppEnd:2
  • $AppClick:4
  • AppViewScreen:8 例如,开启全埋点中的AppStart 和 $AppClick 事件,那 autoTrackMode 的值就是 5(1 + 4 = 5)

(二)数据采集模块

数据采集模块是 SDK 的核心模块,主要负责准确、完整地采集数据。作为数据采集模块,主要提供了下面 4 个功能:代码埋点、全埋点、点击图、可视化全埋点。

关于这些功能的介绍,可以参考《神策分析 iOS SDK 功能介绍》,这里不再赘述。

在上述 SDK 架构图中可以知道数据采集模块中还包含了预置属性,关于预置属性的含义如下所述:一般情况下,任何用户触发的任何事件都需要携带一些最基本的信息,比如操作系统类型、操作系统版本号、运营商信息、应用程序版本号、设备厂商等,这些信息都可以由 SDK 自动采集,我们把这些由 SDK 默认自动采集的事件信息(属性)称为预置属性。

(三)数据存储模块

为了最大限度地保证事件数据的准确性和及时性,会要求数据采集 SDK 尽快将事件数据同步到服务端。但在某些情况下,例如用户处于断网环境,或者根据实际需求(对用户体验要求比较高的情况)会要求只有在 Wi-Fi 环境中才会同步数据,可能会导致事件数据无法同步或者同步失败。因此,数据采集 SDK 一般采取的策略是:先把事件数据缓存在本地,待符合一定的策略之后,再去同步数据

在 iOS 应用程序中,一般通过文件缓存或数据库缓存的方式进行本地缓存,这两种方式都可以作为数据采集 SDK 中的缓存。其中,数据库缓存一般是指使用 SQLite 数据库。

对于写入性能,SQLite 数据库优于文件。对于读取性能,可以参考 SQLite 官方的 测试结果。根据测试结果可以知道,如果单条数据小于 100 KB 时,从 SQLite 数据库中读取数据速度更快;单条数据大于 100 KB 时,从文件中读取速度更快。当然,SQLite 官方测试的环境是在 Linux 工作站上进行的,上述测试结果肯定会受到硬件和操作系统的影响。我们使用 iPhone 设备进行测试后发现,单条数据的阈值在 20 KB 左右。

因此,一般情况下,数据采集 SDK 都是使用 SQLite 数据库来存储数据,神策分析 iOS SDK 采用的也是 SQLite 数据库存储方案。通过数据库缓存事件数据,可以实现对数据的插入、查询及删除功能。

(四)网络模块

在数据存储模块中,介绍了如何把事件数据存储到客户端本地。如果事件数据一直缓存在本地,是没有意义的。我们还需要把数据同步到服务端,然后再经过服务端的存储、抽取、分析和展现,才能充分发挥数据的价值。因此,网络模块主要负责如何把缓存在本地的事件数据同步给服务端

苹果在 Foundation 框架中,为我们提供了封装好的网络请求相关的 API。但在实际的 iOS 应用程序开发中,开发人员很少会直接基于 Foundation 框架进行开发,绝大部分都会使用第三方库,例如 AFNetworking 等。作为通用的数据采集 SDK,要求尽量不依赖任何第三方库。因此,我们就需要基于 Foundation 框架进行开发。另外,同步数据功能相对比较简单,我们直接使用 Foundation 框架中的 NSURLSession 类即可满足我们的需求。

对于数据同步来说,我们需要指定一些自动数据同步的策略,一方面是为了降低用户使用 SDK 的难度和成本,另一方面更是为了确保数据的正确性、完整性和及时性。

在神策分析 iOS SDK 中,我们主要采用了下面三种自动数据同步策略:

策略一:客户端本地存储的数据超过一定条数时同步数据(比如 100 条)每次事件触发并入库后,我们检查一下已缓存的事件条数是否超过了我们定义的阈值,如果已超,则调用 – flush 方法同步数据。
策略二:客户端每隔一定的时间间隔同步一次(比如每隔 15s 就同步一次)通过开启一个定时器,每隔一定时间间隔调用一次 – flush 方法同步数据。
策略三:应用程序进入后台时尽可能同步本地缓存的所有数据应用程序一旦进入后台,下次什么时候启动就不得而知了,因此,每当应用程序进入后台的时候,我们都要尝试同步数据,最大限度的保证数据的完整性。

需要注意的是,上述三种策略是自动数据同步的策略,如果需要手动触发数据同步,可以直接调用 – flush 方法同步数据。

(五)辅助工具

神策分析 iOS SDK 提供了许多埋点相关的工具类,例如 Gzip 压缩、Object 转成 Json 字符串等。关于这些辅助工具的功能和实现就不逐一介绍了,具体可以参考 SDK 的源码。

(六)日志服务

在 SDK 的使用过程中可能会遇到各种各样的问题,通过控制台输出的日志可以帮助我们迅速排查问题。扫码打开调试模式后,SDK 同时自动开启日志输出功能;也可在测试阶段通过 – enableLog: 接口打开 SDK 日志输出功能。

SDK 日志输出功能开启后,在 IDE(如 Xcode)控制台中筛选 SALog 关键词,可以看到埋点触发和数据上报相关的日志,如下所示:

*   埋点事件触发成功时,SDK 会输出【track event】开头的事件数据

*   埋点事件触发失败时,SDK 会输出相应的错误原因

*   事件数据上报成功时,SDK 会输出【valid message】字段开头的事件数据

*   事件数据上报失败时,SDK 会输出【invalid message】字段开头的事件数据并输出错误原因

例如,下图标识了一个事件数据上报成功的日志:

图 点击放大,查看更清晰

总结

本文围绕神策分析 iOS SDK 的架构进行了全面的介绍,旨在让大家对于 SDK 的架构有一个清晰的了解。关于 SDK 的具体技术实现等相关知识,会在后续的文章中逐步向大家介绍。

如果你喜欢更多内容,欢迎关注「神策数据开源社区服务号」,也可以在服务号回复“ 3 ”,获取进入开源社区社群的方式,和一群热爱技术的人聊技术、分享技术!

声明:本文章版权为神策数据所有,未经授权不得以任何形式转载,申请内容转载,请添加微信号 wafree 联系策小编。

点击开源社区官网,进入官网~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容