Data Collection Custom Rules¶
View¶
Requires enabling the configuration FTRUMConfig.enableTraceUserView = YES.
rumConfig.viewTrackingHandler = [CustomViewTracker new];
#import "FTDefaultUIKitViewTrackingHandler.h"
// Protocol implementation example
@interface CustomViewTracker : NSObject <FTUIKitViewTrackingHandler>
// Only add when SDK's default view collection rules are needed
@property (nonatomic, strong) FTDefaultUIKitViewTrackingHandler defaultHandler;
@end
@implementation CustomViewTracker
// Only add when SDK's default view collection rules are needed
-(FTDefaultUIKitViewTrackingHandler *)defaultHandler{
if (!_defaultHandler) {
_defaultHandler = [FTDefaultUIKitViewTrackingHandler new];
}
return _defaultHandler;
}
- (FTRUMView *)rumViewForViewController:(UIViewController *)viewController {
// Exact match by class name
if ([viewController isKindOfClass:[HomeViewController class]]) {
return [[FTRUMView alloc] initWithViewName:@"main_home" property:@{@"page_type": @"home"}];
}
// Filter by prefix
else if ([NSStringFromClass([viewController class]) hasPrefix:@"FT"]) {
return [[FTRUMView alloc] initWithViewName:[NSString stringWithFormat:@"ft_%@", NSStringFromClass([viewController class])] property:nil];
}
// Set by accessibilityLabel
else if (viewController.view.accessibilityLabel) {
return [[FTRUMView alloc] initWithViewName:viewController.view.accessibilityLabel property:nil];
}
// After customizing some pages, use SDK's default collection rules for the remaining pages (return the result of the default handler)
return [self.defaultHandler rumViewForViewController:viewController];
// Return nil directly to skip tracking
return nil;
}
@end
rumConfig.viewTrackingHandler = CustomViewTracker()
class CustomViewTracker: NSObject, FTUIKitViewTrackingHandler {
// Only keep this property when SDK's default view collection rules are needed
lazy var defaultHandler: FTDefaultUIKitViewTrackingHandler = {
FTDefaultUIKitViewTrackingHandler()
}()
func rumView(for viewController: UIViewController) -> FTRUMView? {
// Exact match by class name
if viewController is HomeViewController {
let properties: [String: Any] = ["page_type": "home"]
return FTRUMView(viewName: "main_home", property: properties)
}
// Filter by class name prefix
let vcClassName = String(describing: type(of: viewController))
if vcClassName.hasPrefix("FT") {
let viewName = "ft_\(vcClassName)"
return FTRUMView(viewName: viewName, property: nil)
}
// Set by accessibilityLabel
if let accessibilityLabel = viewController.view.accessibilityLabel, !accessibilityLabel.isEmpty {
return FTRUMView(viewName: accessibilityLabel, property: nil)
}
// After customizing some pages, use SDK's default collection rules for the remaining pages (return the result of the default handler)
return defaultHandler.rumView(for: viewController)
// Return nil directly to skip tracking
return nil
}
}
Action¶
Requires enabling the configuration FTRUMConfig.enableTraceUserAction = YES.
rumConfig.actionTrackingHandler = [CustomActionTracker new];
#import "FTDefaultActionTrackingHandler.h"
// Protocol implementation example
// In iOS environment, must conform to the `FTUIPressRUMActionsHandler` protocol
// In tvOS environment, must conform to the `FTUITouchRUMActionsHandler` protocol.
@interface CustomActionTracker : NSObject <FTUIPressRUMActionsHandler,FTUITouchRUMActionsHandler>
// Only add when SDK's default Action collection rules are needed
@property (nonatomic, strong) FTDefaultActionTrackingHandler defaultHandler;
@end
@implementation CustomActionTracker
// Only add when SDK's default Action collection rules are needed
-(FTDefaultActionTrackingHandler *)defaultHandler{
if (!_defaultHandler) {
_defaultHandler = [FTDefaultActionTrackingHandler new];
}
return _defaultHandler;
}
// Protocol method required for both iOS and tvOS
- (nullable FTRUMAction *)rumLaunchActionWithLaunchType:(FTLaunchType)type {
if(type == FTLaunchCold){
return [[FTRUMAction alloc]initWithActionName:@"cold"];
}
// Return nil to skip tracking
return nil;
}
// Protocol method required for iOS environment
-(nullable FTRUMAction *)rumActionWithTargetView:(UIView *)targetView{
if (view.accessibilityIdentifier){
return [[FTRUMAction alloc] initWithActionName:view.accessibilityIdentifier];
}
// After customizing some Actions, use SDK's default collection rules for the remaining ones (return the result of the default handler)
return [self.defaultHandler rumActionWithTargetView:targetView];
// Return nil to skip tracking
return nil;
}
// Protocol method required for tvOS environment
- (nullable FTRUMAction *)rumActionWithPressType:(UIPressType)type targetView:(UIView *)targetView{
if (type == UIPressTypeSelect && view.accessibilityIdentifier){
return [[FTRUMAction alloc] initWithActionName:view.accessibilityIdentifier];
}
// After customizing some Actions, use SDK's default collection rules for the remaining ones (return the result of the default handler)
return [self.defaultHandler rumActionWithPressType:type targetView:targetView];
// Return nil to skip tracking
return nil;
}
@end
rumConfig.actionTrackingHandler = CustomActionTracker()
// Protocol implementation example
// In iOS environment, must conform to the `FTUIPressRUMActionsHandler` protocol
// In tvOS environment, must conform to the `FTUITouchRUMActionsHandler` protocol.
class CustomActionTracker: NSObject, FTUIPressRUMActionsHandler, FTUITouchRUMActionsHandler {
// Only add when SDK's default Action collection rules are needed
lazy var defaultHandler: FTDefaultActionTrackingHandler = {
FTDefaultActionTrackingHandler()
}()
// Protocol method required for both iOS and tvOS
func rumLaunchAction(with type: FTLaunchType) -> FTRUMAction? {
if type == .cold {
return FTRUMAction(actionName: "cold")
}
// Return nil to skip tracking
return nil
}
// Protocol method required for iOS environment
func rumAction(withTargetView targetView: UIView) -> FTRUMAction? {
if let identifier = targetView.accessibilityIdentifier {
return FTRUMAction(actionName: identifier)
}
// After customizing some Actions, use SDK's default collection rules for the remaining ones (return the result of the default handler)
return defaultHandler.rumAction(withTargetView: targetView)
// Return nil to skip tracking
return nil
}
// Protocol method required for tvOS environment
func rumAction(with pressType: UIPress.PressType, targetView: UIView) -> FTRUMAction? {
if pressType == .select, let identifier = targetView.accessibilityIdentifier {
return FTRUMAction(actionName: identifier)
}
// After customizing some Actions, use SDK's default collection rules for the remaining ones (return the result of the default handler)
return defaultHandler.rumAction(with: pressType, targetView: targetView)
// Return nil to skip tracking
return nil
}
}
Resource¶
Requires enabling the configuration FTRUMConfig.enableTraceUserResource = YES or Custom Network collection via forwarding URLSession Delegate
Filter collection based on URL¶
Add custom properties¶
By setting a property provider closure, you can return additional properties to be attached to the RUM Resource.
For example, you might want to add the HTTP request body to the RUM Resource:
rumConfig.resourcePropertyProvider = ^NSDictionary *_Nullable(NSURLRequest *request, NSURLResponse *response,NSData *data, NSError *error) {
NSString *body = @"";
if (request.HTTPBody) {
body = [[NSString alloc] initWithData:httpBody encoding:NSUTF8StringEncoding] ?: @"";
}
return @{@"request_body": body};
}
Filter network errors¶
When a network request encounters an error, an Error data of type network_error is generated in RUM. Some URLSession local errors, like task.cancel, are normal logic within the user program and are not error data. In such cases, you can use the sessionTaskErrorFilter callback for interception and filtering. Confirm interception by returning YES, do not intercept by returning NO. After interception, RUM-Error will not collect this error.