Building a High‑Precision Full‑Chain Event Tracking System for Mobile Apps
This article presents a comprehensive, high‑precision, stable, and full‑link event tracking solution for iOS, Android, and H5 clients, detailing the shortcomings of traditional point‑tracking, the design of objects and a virtual tree (VTree), AOP‑based click handling, exposure tracking via VTree diffs, performance optimizations, refer‑based link tracing, and integration with H5/RN, all validated in the NetEase Cloud Music ecosystem.
Background
In the mobile‑internet era, rapid product iteration requires highly accurate, stable, and full‑link data collection on the client side. Traditional point‑tracking methods cause low precision, high maintenance cost, and difficulty in funnel or attribution analysis.
Problems with Traditional Point Tracking
Simple event points (click, double‑click, swipe) are easy to implement but lack context.
Exposure tracking for list and non‑list resources is a nightmare; achieving 99.99% precision is extremely hard.
Each point is independent, requiring unique naming and leading to massive duplicate parameters.
Funnel and attribution analysis need “magic parameters” to link unrelated points.
Points are a black box, making management and cost high.
Previous Attempts
Zero‑Trace Tracking
Automatic generation of XPaths for simple events was tried, but it proved unstable, hard to maintain, and unsuitable for high‑precision scenarios, especially for exposure tracking where the system cannot reliably identify resource cells.
Our Solution
Object Model
Each UI element is treated as an object identified by an _oid. Objects are classified into two categories: page (e.g., UIViewController.view, WebView) and element (e.g., UIButton, custom view). Objects carry their own parameters and can be reused across the UI.
Virtual Tree (VTree)
Objects are organized into a virtual tree that is a subset of the original view hierarchy. Each node knows its ancestors, forming an SPM value that uniquely locates the node. The VTree is continuously rebuilt whenever a view changes (add, delete, layout, visibility, etc.).
Event Format
{
"_elist": [{"_oid":"element_oid","_pos":"optional_position","biz_param":"optional"}],
"_plist": [{"_oid":"page_oid","_pos":"optional_position","_pgstep":"page_depth"}],
"_spm":"node_position",
"_scm":"node_content",
"_sessid":"session_id",
"_eventcode":"_ec/_ev/_ed/_pv/_pd",
"_duration":"milliseconds"
}Key fields: _eventcode: event type (click, exposure start/end, page view, etc.). _elist: ordered list of element nodes from the target up to the root. _plist: ordered list of page nodes. _spm: unique identifier derived from the node’s ancestors.
The data structure is hierarchical, not a collection of independent points.
Click Event Hooking
Four common click scenarios are intercepted using AOP:
TapGesture on
UIView UIControlactions (e.g., TouchUpInside) UITableViewCell selection UICollectionViewCell selection
Method swizzling adds pre‑ and after‑hooks to the original methods, allowing developers to inject tracing code without modifying business logic.
@interface UIViewEventTracingAOPTapGesHandler : NSObject
@property (nonatomic, assign) BOOL isPre;
- (void)view_action_gestureRecognizerEvent:(UITapGestureRecognizer *)gestureRecognizer;
@end
@implementation UIViewEventTracingAOPTapGesHandler
- (void)view_action_gestureRecognizerEvent:(UITapGestureRecognizer *)gestureRecognizer {
if (!self.isPre) {
// after‑hook logic
} else {
// pre‑hook logic
}
}
@endExposure Tracking via VTree Diff
Exposure events are derived automatically by diffing two consecutive VTrees. Nodes present in the previous tree but missing in the new one indicate exposure end; nodes newly appearing indicate exposure start. This eliminates manual exposure timing and works uniformly for list and non‑list resources.
Development Steps
Assign an _oid to each view to create objects and build the VTree.
Set business parameters on each object.
VTree Construction Details
A node is visible only if its hidden flag is false, alpha > 0, and it is attached to a window.
Child visible area must be within the parent’s visible area; developers can enlarge or shrink it similar to contentEdgeInsets.
Nodes can be occluded by later‑added page nodes.
Logical mounting allows manual or automatic re‑parenting, and SPM‑based mounting for decoupling.
Performance Optimizations
VTree construction is throttled to the main‑runloop idle time and limited to 16.7 ms / 3 (≈5.6 ms) per frame. A run‑loop observer with a duration throttle (default 0.1 s) ensures the process does not block the UI thread.
_throtte = [[NEEventTracingTraversalRunnerDurationThrottle alloc] init];
_throtte.tolerentDuration = 0.1f;
_throtte.callback = self;
CFRunLoopObserverContext context = {0, (__bridge void *)self, NULL, NULL, NULL};
_runloopObserver = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, LONG_MAX, &ETRunloopObserverCallback, &context);Benchmarks on iPhone 12 show full‑tree construction costs 3–8 ms (CPU 2‑3 %) and partial‑tree construction during scrolling costs 1–2 ms, far lower than the previous 10 % CPU usage of the legacy exposure component.
Link Tracing (Refer)
Each event carries a formatted refer string that uniquely identifies the point in the data warehouse, enabling end‑to‑end funnel and attribution analysis. The refer format includes session ID, page step, act sequence, SPM, SCM, and optional flags.
[timestamp]#[rand]#[appver]#[buildver] // _sessid
_pgstep // page exposure order
_actseq // interaction order within a page
spm // node position
scm // node content (cid, ctype, ctraceid, ctrp)Various refer types (_addrefer, _pgrefer, _hsrefer, _rqrefer) support click‑to‑play, page navigation, multi‑step attribution, and cross‑system bridging.
H5 and React‑Native Integration
For RN, a bridge layer assigns _oid and parameters to native views. For in‑app H5, a semi‑white‑box approach builds a partial VTree inside the web view and merges it with the native VTree, achieving seamless cross‑platform tracking.
Visualization and Validation Tools
Because the data is structured, a set of visualization tools can display the VTree and associated events, and a validation engine can check the correctness of object parameters and the overall VTree structure. Automated audits run on test and gray‑release builds to catch issues before production.
Deployment and Future Plans
The solution is already deployed across all NetEase Cloud Music apps, with core scenarios validated. Future directions include using VTree for UI automation testing, cross‑platform page identification, richer data visualizations, enhanced H5 tracking, and automated refer verification.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
