可视化全埋点系列文章之元素遍历篇

一、前言

从之前的可视化全埋点系列文章之功能介绍篇可以了解到,可视化全埋点主要功能就是定义 App 上的页面浏览和元素点击事件。因为可以在前端选中 App 上的元素,并对 App 上的元素点击事件重新定义虚拟事件[1],所以前端是需要获取到 App 上的所有元素,主要包括:

1. 元素位置,即元素相对于手机屏幕的坐标

2. 元素尺寸,元素的尺寸大小,用于前端渲染

3. 元素信息,包括元素标识、元素位置和内容等,用于定义事件

这其实就是可视化全埋点为什么需要元素遍历的原因。

二、什么是元素遍历

2.1 概念

介绍元素遍历之前,先说明一下本文中的元素。可视化全埋点用于可点击元素的圈选,只需要关注用户交互元素。因此这里的元素指的是 UI 元素,表示我们在 App 里可以看见的任何元素。有些元素用于响应交互,比如 UIButton、UITableView、UISwitch、UISegmentedControl 等。有些元素用于提供丰富的内容,比如 UIImageView、UILabel、Web 容器(WebView)等。

元素遍历,顾名思义,就是查询遍历 App 内的所有元素。虽然最终我们需要圈选埋点的只是可点击元素,但是因为需要递归去找到所有可点击元素,并且可点击元素可能是普通元素的子元素,所以在遍历查询过程中,不可避免地需要找到其他非点击元素,比如 UIView、UIViewController、UIWindow 等。

2.2 注意事项

在元素遍历过程中,有几点需要注意:

  • 不重:即同一个元素,不能被重复找到,避免数据冗余,优化上传性能。比如针对不同类型的元素,可能需要采取不同的查找策略,保证同一个元素最终只会被找到一次

  • 不漏:不能遗漏可交互元素,否则可能导致该元素无法圈选,从而无法定义可视化全埋点事件

  • 不多:需要忽略 App 中无法交互的元素,比如设置隐藏、透明或超出屏幕的元素。如果找到了不可见的元素并在前端渲染,可能影响正常元素的圈 

三、如何进行元素遍历

元素遍历,并使用某个可点击元素定义可视化全埋点事件,需要解决的几个关键问题总结如下:

1. 首先需要找到元素,也就是从运行中的 App 中遍历找到所有元素

2. 获取状态,即标记这个元素是否可以定义事件

3. 元素位置,计算元素位置,从而在前端进行渲染

4. 优先级,即如果两个元素坐标重叠,前端鼠标 hover 后,应该优先响应哪个元素

下面介绍如何解决上述问题。

3.1 可见性

在页面层级中,有很多元素是不可见的,比如被隐藏或者超出屏幕。这些元素不可交互,在元素遍历过程中需要进行移除。

元素不可见的常见原因如下:

1. 设置隐藏

2. 设置透明度小于 0.01(iOS 中,透明度小于 0.01 即不可见)

3. 尺寸为 0 或超出屏幕

4. 从父视图移出

针对上述原因导致的元素不可见,需要进行屏蔽,实现如下:

// 判断一个 view 是否显示
- (BOOL)sensorsdata_isVisible {
 
    if (!(self.window && self.superview)) {
        return NO;
    }
    if(self.alpha <= 0.01 || self.isHidden) {
        return NO;
    }
    // 计算 view 在 keyWindow 上的坐标
    CGRect rect = [self convertRect:self.bounds toView:nil];
    // 若 size 为 CGSizeZero
    if (CGRectIsNull(rect) || CGSizeEqualToSize(rect.size, CGSizeZero)) {
        return NO;
    }
}

 对于被覆盖元素,虽然不可见,但是在 iOS 中,如果覆盖的元素设置不可交互,即 userInteractionEnabled = NO,那么被覆盖的元素仍然可交互(感兴趣的读者可以自行验证一下)。所以被覆盖的元素,暂时不屏蔽。

3.2 元素遍历

元素遍历,就是解决找到元素的问题。关于 iOS 开发中元素遍历,常用的有两种方案,下面我们分别进行探讨。

3.2.1. 方案 1:遍历所有 subviews

3.2.1.1. 方案说明

获取当前 window,一般情况下,直接获取 keyWindow 即可。然后从当前 keyWindow,递归遍历所有子元素,直到没有子元素为止。方案实现相对简单,此处不再展开说明。

3.2.1.2. 优缺点

优点:

1. 维护成本小:从代码实现可以看出,这种方案逻辑简单清晰、方便维护

2. 兼容问题少:直接递归遍历所有 subviews,不需要针对不同元素类型做兼容处理,相对比较稳定

缺点:

1. 存在很多冗余元素:直接递归遍历,会存在大量私有类型或其他冗余元素,比如从 navigationController.view 找到 viewController.view 之间,会经过 UINavigationTransitionView 和 UIViewControllerWrapperView 两个私有类型的 view。同时 UITextField、UIButton 等是通过其他多层子元素组合而成,这些元素也不直接涉及用户交互,属于冗余元素。我们最终需要的,只是 viewController.view 上的各种可交互控件,比如 UIButton、UITableViewCell 等

2. 查找路径比较长:比如从 navigationController.view 找到 viewController.view,或者从 keyWindow 找到 navigationController.view 之前,都存在多层私有 view,导致查找路径比较长,最终影响查询效率和性能。如图 3-1 所示ÿ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可视化埋点和代码埋点都是常见的数据采集方式,但它们的实现方式有所不同。 代码埋点指的是在应用程序的代码中嵌入特定的代码段,以便在应用程序运行时收集特定的数据。开发人员需要手动编写和维护这些代码,以确保数据采集的正确性和完整性。 而可视化埋点则是通过可视化界面来配置和管理数据采集,在应用程序中不需要手动编写代码。用户可以在可视化界面中定义需要采集的页面元素或事件,并指定需要采集的数据类型和参数。这些配置信息会被转换为代码,自动插入到应用程序中。 下面是两种埋点方式的对比: 1. 实现难度:代码埋点需要开发人员手动编写和维护代码,需要一定的技术能力。而可视化埋点则不需要编写代码,只需要通过可视化界面进行配置。 2. 精度和完整性:代码埋点可以采集更详细和准确的数据,因为开发人员可以更精细地控制采集的过程。而可视化埋点则有可能遗漏某些数据,或者采集到错误的数据,因为它是通过配置界面来实现的。 3. 可维护性:代码埋点需要开发人员手动编写和维护代码,对于大型应用程序来说,维护成本会很高。而可视化埋点则可以通过可视化界面进行修改和维护,对于非开发人员来说更加容易。 综上所述,代码埋点可视化埋点各有优缺点,选择哪种方式需要考虑具体情况。如果需要采集更详细和准确的数据,或者应用程序比较小,那么代码埋点可能更适合;如果需要快速配置和管理数据采集,或者应用程序比较大,那么可视化埋点可能更适合。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值