iOS 實現UIButton自動化點擊埋點

思路:我們HOOK UIControl的 addtarget:action:forControlEvents方法,交換UIControl的 addtarget:action:forControlEvents
方法的實現, 在交換的方法中添加原來響應的同時,再添加一個埋點響應,該響應方法實現了點擊埋點操作,同時要添加一個標記為,記錄我們添加過
點擊埋點響應了,防止外部再次添加響應的時候,我們這里重復添加埋點響應,同時,還要hook removeTarget:action:forControlEvents方法,在該方法中記錄我們綁定的點擊處理次數,當次數大于0時,進行埋點上報

一下是我們的實現代碼

static const void *lbmonitorActionNameKey = "monitorActionNameKey";
static const void *lbSenderAction = "lbSenderAction";
static const void *lbTabButtonId = "lbTabButtonId";
static const void *lbClickActionCounts = "lbClickActionCounts";@implementation UIControl (LB)
@dynamic actionName;+ (void)load
{lbinstanceMethod_fastExchangeImplementations([self class], @selector(addTarget:action:forControlEvents:), [self class], @selector(lbtracker_addCagegoryTarget:action:forControlEvents:));instanceMethod_fastExchangeImplementations([self class], @selector(removeTarget:action:forControlEvents:), [self class], @selector(lbtracker_removeCagegoryTarget:action:forControlEvents:));
}- (void)lbtracker_addCagegoryTarget:(id)targetaction:(SEL)actionforControlEvents:(UIControlEvents)controlEvents
{// 自動化埋點:只針對”點擊“進行埋點,一次點擊一次上報,且先埋點后業務。if ([self isKindOfClass:[UITextField class]] == NO && controlEvents == UIControlEventTouchUpInside) {// 避免:業務添加多次點擊回調時,觸發多次埋點或者點擊處理順序錯亂。NSNumber *hookClickMethod = objc_getAssociatedObject(self, "lb_track_click");NSLog(@"哈哈哈哈哈這里的hookClickMethod%@ %@", self, hookClickMethod);if (!hookClickMethod) {objc_setAssociatedObject(self, "lb_track_click", @(1), OBJC_ASSOCIATION_RETAIN);[self setSenderAction:NSStringFromSelector(action)];[self autotracker_addCagegoryTarget:selfaction:@selector(autotracker_monitorAction:forEvent:)forControlEvents:controlEvents];}// 記錄控件綁定點擊處理次數,當次數大于0時,進行點擊埋點上報。NSArray *actionNames = [self actionsForTarget:target forControlEvent:controlEvents];NSLog(@"哈哈哈哈哈這里這里的數量數量%@ %@", actionNames, NSStringFromSelector(action));if (actionNames.count == 0 || ![actionNames containsObject:NSStringFromSelector(action)]) {NSLog(@"這里的原始數量%ld %@", [self lbtracker_clickActionCounts], self);[self setAutotracker_clickActionCounts:[self autotracker_clickActionCounts] + 1];}}[self autotracker_addCagegoryTarget:targetaction:actionforControlEvents:controlEvents];
}- (void)lbtracker_removeCagegoryTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
{// 減少控件綁定點擊處理次數,當次數大于0時,進行點擊埋點上報。NSArray *actionNames = [self actionsForTarget:target forControlEvent:controlEvents];if (actionNames.count > 0 && [actionNames containsObject:NSStringFromSelector(action)]) {APLogInfo(@"AutoTrack", @"Click %@ remove T", NSStringFromSelector(action));[self setlbTracker_clickActionCounts:[self lbtracker_clickActionCounts] - 1];}[self lbtracker_removeCagegoryTarget:target action:action forControlEvents:controlEvents];
}- (void)lbtracker_monitorAction:(UIControl *)sender forEvent:(UIEvent *)event
{LBLog(@"lbTrack", @"Click %@ counts = %@", self.senderAction, @([self lbtracker_clickActionCounts]));if (self.skipTrack || 0 == [self lbtracker_clickActionCounts]) {return;}[self lbtracker_parseClickPoint:event];//執行埋點操作
}- (NSString *)actionName {return objc_getAssociatedObject(self, monitorActionNameKey);
}- (void)setActionName:(NSString *)monitorActionName{objc_setAssociatedObject(self, monitorActionNameKey,monitorActionName,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}- (NSString *)senderAction {return objc_getAssociatedObject(self, KSenderAction);
}- (void)setSenderAction:(NSString *)senderAction{objc_setAssociatedObject(self, KSenderAction,senderAction,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}- (NSString *)tabButtonId {return objc_getAssociatedObject(self, KTabButtonId);
}- (void)setTabButtonId:(NSString *)tabButtonId {objc_setAssociatedObject(self, KTabButtonId, tabButtonId, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}- (NSInteger)autotracker_clickActionCounts
{NSNumber *counts = objc_getAssociatedObject(self, LBClickActionCounts);return [counts integerValue];
}- (void)setLBtracker_clickActionCounts:(NSInteger)count
{NSLog(@"這里的數量這里的數量%ld", count);objc_setAssociatedObject(self, LBClickActionCounts, @(count), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}- (void)lbtracker_parseClickPoint:(UIEvent *)event
{// 獲取點擊位置坐標CGPoint clickPoint;UITouch *touch = [event touchesForView:self].anyObject;if (touch) {clickPoint = [touch locationInView:self];}if ([self respondsToSelector:@selector(lbLogModel_auk)]) {LBLogModel *model = [self performSelector:@selector(lbLogModel_auk)];model.clickPoint = clickPoint;}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/71178.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/71178.shtml
英文地址,請注明出處:http://en.pswp.cn/web/71178.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++藍橋杯基礎篇(六)

片頭 嗨~小伙伴們,大家好!今天我們來一起學習藍橋杯基礎篇(六),練習相關的數組習題,準備好了嗎?咱們開始咯! 第1題 數組的左方區域 這道題,實質上是找規律,…

git -學習筆記

目錄 基本操作語法 設置用戶和郵箱 版本回退 工作區和暫存區 撤銷修改 刪除與恢復 一工作區刪除了,但是暫存區沒刪除 二工作區誤刪了,暫存區還有 github-Git 連接 報錯解決-push遠程倉庫被拒絕 遠程庫 分支 分支沖突 儲藏分支 回到當前分…

Windows本地Docker+Open-WebUI部署DeepSeek

最近想在自己的電腦本地部署一下DeepSeek試試,由于不希望污染電腦的Windows環境,所以在wsl中安裝了ollama,使用ollama拉取DeepSeek模型。然后在Windows中安裝了Docker Desktop,在Docker中部署了Open-WebUI,最后再在Ope…

力扣785. 判斷二分圖

力扣785. 判斷二分圖 題目 題目解析及思路 題目要求將所有節點分成兩部分,每條邊的兩個端點都必須在不同集合中 二分圖:BFS/DFS/并查集 因為圖不一定聯通,所以枚舉所有點都做bfs(如果沒聯通的話) 代碼 class Solution { public:bool is…

springboot之集成Elasticsearch

目錄 二、Elasticsearch 是什么?三、Elasticsearch 安裝四、Springboot 集成 Elasticsearch 的方式五、創建項目集成 Elasticsearch 2.創建 Spring Initializr 項目 es (3).新建實體類 User(4).新建 dao 接口類 UserR…

[Lc滑動窗口_1] 長度最小的數組 | 無重復字符的最長子串 | 最大連續1的個數 III | 將 x 減到 0 的最小操作數

目錄 1. 長度最小的字數組 題解 代碼 ?2.無重復字符的最長子串 題解 代碼 3.最大連續1的個數 III 題解 代碼 4.將 x 減到 0 的最小操作數 題解 代碼 1. 長度最小的字數組 題目鏈接:209.長度最小的字數組 題目分析: 給定一個含有 n 個 正整數 的數組…

數據集筆記:新加坡 地鐵(MRT)和輕軌(LRT)票價

數據連接 data.gov.sg 2024 年 12 月 28 日起生效的新加坡地鐵票價 該數據集包含 MRT 和 LRT 票價的信息,包括: 票價類型(Fare Type):成人票、學生票、老年人票、殘障人士票等。適用時間(Applicable Tim…

湘潭大學計算機復試詳細攻略(調劑)

一,寫在前面的話 ① 首先,能完成考試初試來到這里的都是勇士。不管結果如何,不管成績如何。我都在這里真心的祝福你以后一帆風順。 ② 目前學歷貶值嚴重,如果是成績不理想的話,我建議能工作就去工作,工作不…

【前端基礎】Day 3 CSS-2

目錄 1. Emmet語法 1.1 快速生成HTML結構語法 1.2 快速生成CSS樣式語法 2. CSS的復合選擇器 2.1 后代選擇器 2.2 子選擇器 2.3 并集選擇器 2.4 偽類選擇器 2.4.1 鏈接偽類選擇器 2.4.2 focus偽類選擇器 2.5 復合選擇器總結 3. CSS的元素顯示模式 3.1 什么是元素顯示…

不同數據類型在數據庫和編程語言之間的對應關系表

不同數據類型在數據庫和編程語言之間的對應關系表 MySql 與 C# MySqlC#varcharstringbigintlongbigint unsignedulongintintint unsigneduintsmallintshortsmallint unsignedushortVARCHAR(36)GuidsmalldatetimeDateTimedateDateTimedatetimeDateTimetimestampDateTimefloatf…

RabbitMQ操作實戰

1.RabbitMQ安裝 RabbitMQ Windows 安裝、配置、使用 - 小白教程-騰訊云開發者社區-騰訊云下載erlang:http://www.erlang.org/downloads/https://cloud.tencent.com/developer/article/2192340 Windows 10安裝RabbitMQ及延時消息插件rabbitmq_delayed_message_exch…

DeepSeek教unity------UI元素長按響應

主要功能說明: ?長按檢測:通過記錄指針按下的時間,判斷是否達到 longClickTime,從而觸發長按事件。?狀態管理:使用 StateEnum 枚舉管理點擊項的當前狀態(未按下、按下等待長按、長按已觸發)。…

【北京迅為】itop-3568 開發板openharmony鴻蒙燒寫及測試-第2章OpenHarmony v3.2-Beta4版本測試

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工藝,搭載一顆四核Cortex-A55處理器和Mali G52 2EE 圖形處理器。RK3568 支持4K 解碼和 1080P 編碼,支持SATA/PCIE/USB3.0 外圍接口。RK3568內置獨立NPU,可用于輕量級人工…

stm32hal庫尋跡+藍牙智能車(STM32F103C8T6)

簡介: 這個小車的芯片是STM32F103C8T6,其他的芯片也可以照貓畫虎,基本配置差不多,要注意的就是,管腳復用,管腳的特殊功能,(這點不用擔心,hal庫每個管腳的功能都會給你羅列,很方便的.)由于我做的比較簡單,只是用到了幾個簡單外設.主要是由帶霍爾編碼器電機的車模,電機…

SQL命令詳解之操作數據庫

操作數據庫 SQL是用于管理和操作關系型數據庫的標準語言。數據庫操作是SQL的核心功能之一,主要用于創建、修改和刪除數據庫對象,如數據庫、表、視圖和索引等。以下是SQL中常見的數據庫操作命令及其功能簡介: 1. 查詢數據庫 查詢所有的數據庫…

Go紅隊開發—編解碼工具

文章目錄 開啟一個項目編解碼工具開發Dongle包Base64編解碼摩斯密碼URL加解密AES加解密 MD5碰撞工具開發 開啟一個項目 這作為補充內容,可忽略直接看下面的編解碼: 一開始用就按照下面的步驟即可 1.創建一個文件夾,你自己定義名字(建議只用…

Starrocks入門(二)

1、背景:考慮到Starrocks入門這篇文章,安裝的是3.0.1版本的SR,參考:Starrocks入門-CSDN博客 但是官網的文檔,沒有對應3.0.x版本的資料,卻有3.2或者3.3或者3.4或者3.1或者2.5版本的資料,不要用較…

工程化與框架系列(10)--微前端架構

微前端架構 🏗? 微前端是一種將前端應用分解成更小、更易管理的獨立部分的架構模式。本文將詳細介紹微前端的核心概念、實現方案和最佳實踐。 微前端概述 🌟 💡 小知識:微前端的核心理念是將前端應用分解成一系列獨立部署、松耦…

SwiftUI之狀態管理全解析

文章目錄 引言一、`@State`1.1 基本概念1.2 初始化與默認值1.3 注意事項二、`@Binding`2.1 基本概念2.2 初始化與使用2.3 注意事項三、`@ObservedObject`3.1 基本概念3.2 初始化與使用3.3 注意事項四、`@EnvironmentObject`4.1 基本概念4.2 初始化與使用4.3 注意事項五、`@Stat…

Redis 高可用性:如何讓你的緩存一直在線,穩定運行?

🎯 引言:Redis的高可用性為啥這么重要? 在現代高可用系統中,Redis 是一款不可或缺的分布式緩存與數據庫系統。無論是提升訪問速度,還是實現數據的高效持久化,Redis 都能輕松搞定。可是,當你把 …