iOS SDK 的 H5 打通方案演进 | 数据采集

本文详细介绍了iOS SDK与H5数据打通的四个演进方案,旨在解决数据丢失率、准确性、用户标识和基础功能等问题。方案一通过传匿名ID实现初步打通,方案二引入异步加载的JS SDK,方案三通过修改UA和缓存数据降低数据丢失风险,方案四利用WKWebView的messageHandlers实现更稳定、灵活的打通。每种方案都分析了其实现原理、优缺点,以供开发者参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

图片

一、前言

在介绍 iOS SDK 的 H5 打通方案之前,我们先了解一下什么是 App 与 H5 打通。

所谓 “打通”,是指 H5 集成 JavaScript 数据采集 SDK 后,H5 触发的事件不是直接同步给服务端,而是先发给 App 端的数据采集 SDK,经 App 端数据采集 SDK 二次加工处理后缓存到本地,再经过合适的上传策略同步到服务端。

二、APP 与 H5 打通的原因

关于 App 与 H5 打通的原因,我们主要是从以下几个角度考虑:

2.1 数据丢失率

在业界,App 端采集数据的丢失率一般在 1% 左右,而 H5 采集数据的丢失率一般在 5% 左右(主要是因为缓存、网络或切换页面等原因)。

因此,如果 App 与 H5 打通,H5 触发的所有事件都可以先发给 App 端数据采集 SDK,经过 App 端二次加工处理后存入本地缓存,在符合特定策略之后再进行数据同步,即可把数据丢失率由 5% 降到 1% 左右。

2.2 数据准确性

众所周知,H5 无法直接获取设备相关的信息,只能通过解析 UserAgent 值获取到有限的信息。而解析 UserAgent 值,至少会面临以下两个问题:

(1)有些信息通过解析 UserAgent 值根本获取不到,比如应用程序的版本号、设备具体型号等;

(2)有些信息通过解析 UserAgent 值可以获取到,但内容可能不正确。

如果 App 与 H5 打通,由 App 端数据采集 SDK 补充这些信息,即可确保事件信息的准确性和完整性。

2.3 用户标识

如果用户在 App 端注册或登录之前使用我们的产品,我们一般都是使用匿名 ID 来标识用户。而 App 与 H5 标识匿名用户的规则不一样(iOS 一般使用 IDFA 或 IDFV,H5 一般使用 Cookie),从而就会导致一个用户使用了我们的产品,结果产生了两个匿名用户。如果 App 与 H5 打通,就可以将两个匿名 ID 做归一化处理(以 App 端匿名 ID 为准)。

2.4 基础功能

基于 App 与 H5 打通,可以实现诸如 App 内嵌 H5 可视化全埋点、App 内嵌 H5 弹框等更加高级的功能。

介绍完打通的原因之后,我们来看下 App 与 H5 如何进行打通。

三、打通方案演进

关于 App 与 H5 的打通,曾经一直是我们的一个痛点,为此我们也做了持续地探索和迭代。在这个过程中我们踩了很多坑,也积累了一些经验,现在将按照方案演进的顺序为大家一一介绍这几种方式,并分析其背景、实现和优缺点。

3.1 方案一

3.1.1 背景和原理

iOS SDK 从 v1.6.8 版本开始支持 App 与 H5 打通,也就是打通方案的原始版本。

众所周知,在实际开发中,一个技术方案的使用,都是为了解决某些问题。在早期的事件分析中,H5 的匿名 ID(一般使用 Cookie)经常变化,并且与 App 端(iOS 一般使用 IDFA 或 IDFV)不同。因此,导致一个 App 用户在内嵌 H5 页面的行为序列无法和原生页面的行为联系起来,为业务分析造成很大困扰。但是,如果将 App 端的匿名 ID 传给 H5,就能保证 App 内嵌 H5 页面使用的匿名 ID 和原生页面一致,从而解决上述问题。

原理:

在 WebView 加载 H5 页面完成后,iOS SDK 调用 JS 方法将匿名 ID 传给 JS SDK,JS SDK 采集的埋点数据就可以使用 App 的匿名 ID,从而使得 App 进入 H5 页面前后的用户行为序列准确关联。主要流程如图 3-1 所示:

图片

图 3-1 打通方案一的流程图

3.1.2 具体实现

具体实现主要分为下面几个步骤:

(1)从图 3-1 的打通方案流程可以知道,为了保证 JS SDK 已经加载完成,iOS SDK 需要在 H5 页面加载完成后才能调用 JS 方法传值。那么监听 H5 页面加载完成的时机,便成了打通的关键。

对于 UIWebView 而言,我们知道从 UIWebViewDelegate 的代理方法中可以获取 UIWebView 加载 H5 页面的进度,UIWebViewDelegate 的代理方法如下:

API_UNAVAILABLE(tvos) @protocol UIWebViewDelegate <NSObject> @optional/// 是否开始加载 H5- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType API_DEPRECATED("No longer supported.", ios(2.0, 12.0)); /// 已经开始加载 H5- (void)webViewDidStartLoad:(UIWebView *)webView API_DEPRECATED("No longer supported.", ios(2.0, 12.0)); /// H5 页面加载完成- (void)webViewDidFinishLoad:(UIWebView *)webView API_DEPRECATED("No longer supported.", ios(2.0, 12.0)); /// H5 页面加载失败- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error API_DEPRECATED("No longer supported.", ios(2.0, 12.0)); @end

因此,我们在 UIWebView 的 H5 页面加载完成调用 JS 方法,只需要实现 - webViewDidFinishLoad: 方法即可,如下所示:

UIWebView

​​​​​​​
- (void)webViewDidFinishLoad:(UIWebView *)webView {
  
      [[SensorsAnalyticsSDK sharedInstance] showUpWebView:webView];}

对于 WKWebView 而言,查阅 Apple 的 WKWebView 相关 API 文档没有合适的代理方法去监听 H5 页面加载完成,不过发现了 loading 这个属性,说明如下:​​​​​​​

/*! @abstract A Boolean value indicating whether the view is currently loading content. @discussion @link WKWebView @/link is key-value observing (KVO) compliant for this property. */@property (nonatomic, readonly, getter=isLoading) BOOL loading;

loading 属性表示当前页面是否正在加载,如果 loading = NO(即页面不再加载了),表示 H5 页面已经加载完成。因此,我们使用 KVO 监听 loading 的属性变化,就可以知道 WKWebView 加载 H5 页面是否完成,具体实现如下所示:

WKWebView​​​​​​​

// 通过观察者监听 WKWebView 加载进度[_webView addObserver:self forKeyPath:@"loading" options:NSKeyValueObservingOptionNew context:nil]; - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
  
      if (!_webView.loading) {
  
          [[SensorsAnalyticsSDK sharedInstance] showU
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值