Skip to content

RUM Configuration

RUM Initialization Configuration

    // Enable RUM
    FTRumConfig *rumConfig = [[FTRumConfig alloc]initWithAppid:appid];
    rumConfig.enableTraceUserView = YES;
    rumConfig.deviceMetricsMonitorType = FTDeviceMetricsMonitorAll;
    rumConfig.monitorFrequency = FTMonitorFrequencyRare;
    rumConfig.enableTraceUserAction = YES;
    rumConfig.enableTraceUserResource = YES;
    rumConfig.enableTrackAppFreeze = YES;
    rumConfig.enableTrackAppCrash = YES;
    rumConfig.enableTrackAppANR = YES;
    rumConfig.errorMonitorType = FTErrorMonitorAll;
    [[FTMobileAgent sharedInstance] startRumWithConfigOptions:rumConfig];
    let rumConfig = FTRumConfig(appid: appid)
    rumConfig.enableTraceUserView = true
    rumConfig.deviceMetricsMonitorType = .all
    rumConfig.monitorFrequency = .rare
    rumConfig.enableTraceUserAction = true
    rumConfig.enableTraceUserResource = true
    rumConfig.enableTrackAppFreeze = true
    rumConfig.enableTrackAppCrash = true
    rumConfig.enableTrackAppANR = true
    rumConfig.errorMonitorType = .all
    FTMobileAgent.sharedInstance().startRum(withConfigOptions: rumConfig)
Property Type Required Description
appid NSString Yes The unique identifier of the Real User Monitoring (RUM) application. Corresponds to the RUM appid setting; RUM data collection is enabled only when this is set. How to obtain the appid
sampleRate int No Sampling rate. Range [0,100], 0 means no collection, 100 means full collection. Default value is 100. Scoped to all View, Action, LongTask, and Error data under the same session_id.
sessionOnErrorSampleRate int No Sets the error collection rate. When a session is not sampled by sampleRate, if an error occurs during the session, data from the 1 minute before the error can be collected. Range [0,100], 0 means no collection, 100 means full collection. Default value is 0. Scoped to all View, Action, LongTask, and Error data under the same session_id. Supported from SDK 1.5.16 onwards.
enableTrackAppCrash BOOL No Whether to collect crash logs. Default NO.
enableTrackAppANR BOOL No Collect ANR (Application Not Responding) events. Default NO.
enableTrackAppFreeze BOOL No Collect UI freeze events. Default NO. Use -setEnableTrackAppFreeze:freezeDurationMs: to enable freeze collection and set the freeze threshold.
freezeDurationMs long No The threshold for UI freezes, in milliseconds. Range [100,), default 250ms. Supported from SDK 1.5.7 onwards.
enableTraceUserView BOOL No Whether to track user View operations. Default NO.
enableTraceUserAction BOOL No Whether to track user Action operations. Default NO. You can customize action_name via view.accessibilityIdentifier.
enableTraceUserResource BOOL No Whether to track user network requests. Default NO, only affects native HTTP. Note: Network requests initiated via [NSURLSession sharedSession] cannot collect performance data. SDK 1.5.9 and later support collecting network requests initiated via Swift's URLSession async/await APIs.
resourceUrlHandler FTResourceUrlHandler No Custom rules for collecting resources. By default, no filtering. Return NO to collect, YES to skip.
errorMonitorType FTErrorMonitorType No Supplementary monitoring type for error events. Adds monitoring information to collected crash data. FTErrorMonitorBattery for battery level, FTErrorMonitorMemory for memory usage, FTErrorMonitorCpu for CPU usage. Not set by default.
deviceMetricsMonitorType FTDeviceMetricsMonitorType No Performance monitoring type for views. Not set by default. Adds corresponding monitoring item information to collected View data. FTDeviceMetricsMonitorMemory monitors current app memory usage, FTDeviceMetricsMonitorCpu monitors CPU jump count, FTDeviceMetricsMonitorFps monitors screen frame rate.
monitorFrequency FTMonitorFrequency No Sampling period for view performance monitoring. FTMonitorFrequencyDefault 500ms (default), FTMonitorFrequencyFrequent 100ms, FTMonitorFrequencyRare 1000ms.
enableResourceHostIP BOOL No Whether to collect the IP address of the request target domain. Supported on >= iOS 13.0, >= tvOS 13.0.
globalContext NSDictionary No Add custom tags to distinguish user monitoring data sources. If you need to use the tracking feature, set the parameter key to track_id and value to any number. See here for adding rules.
rumCacheLimitCount int No Maximum RUM cache count. Default 100,000. Supported from SDK 1.5.8 onwards.
rumDiscardType FTRUMCacheDiscard No Sets the RUM discard rule. Default FTRUMCacheDiscard. FTRUMCacheDiscard discards appended data when the RUM data count exceeds the maximum; FTRUMDiscardOldest discards old data when the RUM data count exceeds the maximum. Supported from SDK 1.5.8 onwards.
resourcePropertyProvider FTResourcePropertyProvider No Add custom attributes to RUM Resource via a block callback. Supported from SDK 1.5.10 onwards. Lower priority than URLSession custom collection.
enableTraceWebView BOOL No Whether to enable collecting WebView data. Default YES. Supported from SDK 1.5.17 onwards.
allowWebViewHost NSArray No Sets the allowed WebView host addresses for data tracking. When nil, all hosts are collected. Default is nil. Supported from SDK 1.5.17 onwards.
sessionTaskErrorFilter FTSessionTaskErrorFilter No Whether to intercept URLSessionTask errors. Return YES to intercept, NO to not intercept. When intercepted, the error is not collected as a RUM-Error. Supported from SDK 1.5.17 onwards.
issueDataProvider FTIssueDataProvider No Synchronously add custom fields to Crash and ANR RUM Errors automatically collected by the SDK. Requires enableTrackAppCrash or enableTrackAppANR to be enabled. Supported from SDK 1.6.7 onwards. See Error custom fields for usage.
viewTrackingHandler FTViewTrackingHandler No Custom logic for tracking Views, used to decide which ViewControllers should be monitored as RUM Views and to customize the View Name. Prerequisite: enableTraceUserView = YES. Supported from SDK 1.5.18 onwards. See usage example here.
swiftUIViewTrackingHandler FTSwiftUIViewTrackingHandler No Experimental. Custom logic for automatic SwiftUI View collection, used to filter automatically extracted SwiftUI View Names and customize RUM View Names. Prerequisite: enableTraceUserView = YES and this configuration is not nil. If no custom filtering or naming is needed, set FTDefaultSwiftUIViewTrackingHandler. This experimental API may change in future versions. Supported from SDK 1.6.4 onwards. See usage example here.
actionTrackingHandler FTActionTrackingHandler No Custom logic for tracking Actions, used to filter which RUM Action events to record and to customize the Action Name. Prerequisite: enableTraceUserAction = YES. Supported from SDK 1.5.18 onwards. See usage example here.
crashMonitoring FTCrashMonitorType No Configures the scope of crash monitoring types for the SDK. Default is FTCrashMonitorTypeHighCompatibility (high compatibility mode preset macro). Prerequisite: enableTrackAppCrash = YES. Note: You must specify FTCrashMonitorTypeSystem | FTCrashMonitorTypeApplicationState to provide important information for reports. Supported from SDK 1.5.19 onwards.
Sampling Rate Parameter Naming

In SDK 1.6.6 and later, samplerate is deprecated. It is still usable and maps to the same value as sampleRate. For new code, use sampleRate. For versions below 1.6.6, continue using samplerate.

RUM User Data Tracking

FTRUMConfig configures enableTraceUserAction, enableTraceUserView, enableTraceUserResource, enableTrackAppFreeze, enableTrackAppCrash, and enableTrackAppANR to achieve automatic collection of Action, View, Resource, LongTask, and Error data. If you want custom collection, you can report data through FTExternalDataManager.

View

Usage

/// Create a page
///
/// Call this method before `-startViewWithName`. It is used to record the page load time. If load time is not available, this method can be omitted.
/// - Parameters:
///  - viewName: The page name
///  - loadTime: The page load time (nanoseconds)
-(void)onCreateView:(NSString *)viewName loadTime:(NSNumber *)loadTime;

/// Enter a page
/// - Parameters:
///  - viewName: The page name
///  - property: Custom attributes for the event (optional)
-(void)startViewWithName:(NSString *)viewName property:(nullable NSDictionary *)property;

/// Update the load time of the current RUM View.
/// Must be called between `-startView` and `-stopView` methods to take effect.
/// - Parameter duration: The load duration (nanoseconds).
-(void)updateViewLoadingTime:(NSNumber *)duration;

/// Leave a page
/// - Parameter property: Custom attributes for the event (optional)
-(void)stopViewWithProperty:(nullable NSDictionary *)property;
/// Create a page
///
/// Call this method before `-startViewWithName`. It is used to record the page load time. If load time is not available, this method can be omitted.
/// - Parameters:
///  - viewName: The page name
///  - loadTime: The page load time (ns)
open func onCreateView(_ viewName: String, loadTime: NSNumber)

/// Enter a page
/// - Parameters:
///  - viewName: The page name
///  - property: Custom attributes for the event (optional)
open func startView(withName viewName: String, property: [AnyHashable : Any]?)

/// Update the load time of the current RUM View.
/// Must be called between `-startView` and `-stopView` methods to take effect.
/// - Parameter duration: The load duration (nanoseconds).
open func updateViewLoadingTime(_ duration: NSNumber)

/// Leave a page
/// - Parameter property: Custom attributes for the event (optional)
open func stopView(withProperty property: [AnyHashable : Any]?)

Code Examples

- (void)viewDidAppear:(BOOL)animated{
  [super viewDidAppear:animated];
  // Scenario 1:
  [[FTExternalDataManager sharedManager] startViewWithName:@"TestVC"];

  // Scenario 2: Dynamic parameters
  [[FTExternalDataManager sharedManager] startViewWithName:@"TestVC" property:@{@"custom_key":@"custom_value"}];
}
-(void)viewDidDisappear:(BOOL)animated{
  [super viewDidDisappear:animated];
  // Scenario 1:
  [[FTExternalDataManager sharedManager] stopView];

  // Scenario 2: Dynamic parameters
  [[FTExternalDataManager sharedManager] stopViewWithProperty:@{@"custom_key":@"custom_value"}];
}
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    // Scenario 1:
    FTExternalDataManager.shared().startView(withName: "TestVC")
    // Scenario 2: Dynamic parameters
    FTExternalDataManager.shared().startView(withName: "TestVC",property: ["custom_key":"custom_value"])
}
override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    // Scenario 1:
    FTExternalDataManager.shared().stopView()
    // Scenario 2: Dynamic parameters
    FTExternalDataManager.shared().stopView(withProperty: ["custom_key":"custom_value"])
}

SwiftUI View Collection

SwiftUI View supports automatic collection and manual collection:

  • Automatic Collection (Experimental): The SDK automatically identifies pages and uses FTRumConfig.swiftUIViewTrackingHandler for unified filtering and naming. See SwiftUI View Automatic Collection (Experimental).
  • Manual Collection: Use .ftTrackRUMView(name:property:) on a specific SwiftUI View to explicitly mark the page start and end, and customize the View Name and properties. Suitable for scenarios where stable page names are needed, precise control over the View lifecycle is required, or the automatically extracted name is not as expected.
import SwiftUI
import GuanceSDK
struct HomeView: View {
    var body: some View {
        VStack {
            Text("Home")
        }
        .ftTrackRUMView(
            name: "Home",
            property: ["page_type": "home"]
        )
    }
}

Action

Usage

/// Start a RUM Action.
///
/// RUM will bind any Resource, Error, or LongTask events that may be triggered by this Action. Avoid adding multiple actions within 0.1 seconds. At any given time, a View is associated with only one Action. If the previous Action is not finished, a new Action will be discarded.
/// This method does not interfere with the `addAction:actionType:property` method.
///
/// - Parameters:
///   - actionName: The event name
///   - actionType: The event type
///   - property: Custom attributes for the event (optional)
- (void)startAction:(NSString *)actionName actionType:(NSString *)actionType property:(nullable NSDictionary *)property;

/// Add an Action event. No discard logic. Does not bind Resource, Error, or LongTask events.
///
/// This method does not interfere with the RUM Action started by `startAction:actionType:property:`.
/// - Parameters:
///   - actionName: The event name
///   - actionType: The event type
///   - property: Custom attributes for the event (optional)
- (void)addAction:(NSString *)actionName actionType:(NSString *)actionType property:(nullable NSDictionary *)property;
/// Start a RUM Action.
///
/// RUM will bind any Resource, Error, or LongTask events that may be triggered by this Action. Avoid adding multiple actions within 0.1 seconds. At any given time, a View is associated with only one Action. If the previous Action is not finished, a new Action will be discarded.
/// This method does not interfere with the `addAction:actionType:property` method.
///
/// - Parameters:
///   - actionName: The event name
///   - actionType: The event type
///   - property: Custom attributes for the event (optional)
open func startAction(_ actionName: String, actionType: String, property: [AnyHashable : Any]?)

/// Add an Action event. No discard logic. Does not bind Resource, Error, or LongTask events.
///
/// This method does not interfere with the RUM Action started by `startAction:actionType:property:`.
/// - Parameters:
///   - actionName: The event name
///   - actionType: The event type
///   - property: Custom attributes for the event (optional)
open func addAction(_ actionName: String, actionType: String, property: [AnyHashable : Any]?)

Code Examples

// startAction
[[FTExternalDataManager sharedManager] startAction:@"action" actionType:@"click" property:@{@"action_property":@"testActionProperty1"}];
// addAction
[[FTExternalDataManager sharedManager] addAction:@"action" actionType:@"click" property:@{@"action_property":@"testActionProperty1"}];
// startAction
FTExternalDataManager.shared().startAction("custom_action", actionType: "click",property: nil)
// addAction
FTExternalDataManager.shared().addAction("custom_action", actionType: "click",property: nil)

SwiftUI Action Manual Collection

SwiftUI Action needs to be manually added at interaction points. For SwiftUI components such as Button, NavigationLink, List items, or custom gestures, actively record a RUM Action where a user operation occurs.

SwiftUI Action supports two manual collection approaches:

  • Call within an existing event closure: Use FTRUMSwiftUI.trackTapAction(name:property:). This does not add extra gestures and is suitable for Button, NavigationLink, List, scroll views, or scenarios with existing custom gestures.
  • Use a View Modifier: Use .ftTrackRUMTapAction(name:property:count:). This adds a simultaneousGesture to the View. It is suitable for simple tap collection on regular Views.

Note: If the same tap event is already manually collected via FTExternalDataManager, avoid using SwiftUI Action manual collection again to prevent duplicate reporting.

import SwiftUI
import GuanceSDK
struct ProductView: View {
    var body: some View {
        Button("Buy") {
            FTRUMSwiftUI.trackTapAction(
                name: "buy_click",
                property: ["source": "product_detail"]
            )

            // Execute the business tap logic
            buy()
        }
    }

    private func buy() {
        // ...
    }
}
import SwiftUI
import GuanceSDK
struct ProductCard: View {
    var body: some View {
        Text("Buy")
            .ftTrackRUMTapAction(
                name: "buy_click",
                property: ["source": "product_card"]
            )
    }
}

FTRUMSwiftUI.trackTapAction(name:property:) is the recommended manual collection approach, especially for components that already have a tap closure. .ftTrackRUMTapAction(name:property:count:) is a convenient shorthand but adds an extra tap gesture that may interfere with existing interactions in List, NavigationLink, scroll containers, or complex gesture combinations. In such cases, it is recommended to call FTRUMSwiftUI.trackTapAction(name:property:) within the existing tap closure instead.

Error

Usage

/// Add an Error event
/// - Parameters:
///   - type: The error type
///   - message: The error message
///   - stack: The stack trace
///   - property: Custom attributes for the event (optional)
- (void)addErrorWithType:(NSString *)type message:(NSString *)message stack:(NSString *)stack property:(nullable NSDictionary *)property;

/// Add an Error event
/// - Parameters:
///   - type: The error type
///   - state: The application state
///   - message: The error message
///   - stack: The stack trace
///   - property: Custom attributes for the event (optional)
- (void)addErrorWithType:(NSString *)type state:(FTAppState)state  message:(NSString *)message stack:(NSString *)stack property:(nullable NSDictionary *)property;
/// Add an Error event
/// - Parameters:
///   - type: The error type
///   - message: The error message
///   - stack: The stack trace
///   - property: Custom attributes for the event (optional)
open func addError(withType: String, message: String, stack: String, property: [AnyHashable : Any]?)

/// Add an Error event
/// - Parameters:
///   - type: The error type
///   - state: The application state
///   - message: The error message
///   - stack: The stack trace
///   - property: Custom attributes for the event (optional)
open func addError(withType type: String, state: FTAppState, message: String, stack: String, property: [AnyHashable : Any]?)

Code Examples

// Scenario 1
[[FTExternalDataManager sharedManager] addErrorWithType:@"type" message:@"message" stack:@"stack"];
// Scenario 2: Dynamic parameters
[[FTExternalDataManager sharedManager] addErrorWithType:@"ios_crash" message:@"crash_message" stack:@"crash_stack" property:@{@"custom_key":@"custom_value"}];
// Scenario 3: Dynamic parameters
[[FTExternalDataManager sharedManager] addErrorWithType:@"ios_crash" state:FTAppStateUnknown message:@"crash_message" stack:@"crash_stack" property:@{@"custom_key":@"custom_value"}];
// Scenario 1
FTExternalDataManager.shared().addError(withType: "custom_type", message: "custom_message", stack: "custom_stack")
// Scenario 2: Dynamic parameters
FTExternalDataManager.shared().addError(withType: "custom_type", message: "custom_message", stack: "custom_stack",property: ["custom_key":"custom_value"])
// Scenario 3: Dynamic parameters
FTExternalDataManager.shared().addError(withType: "custom_type", state: .unknown, message: "custom_message", stack: "custom_stack", property: ["custom_key":"custom_value"])

LongTask

Usage

/// Add a freeze event
/// - Parameters:
///   - stack: The freeze stack trace
///   - duration: The freeze duration (nanoseconds)
///   - property: Custom attributes for the event (optional)
- (void)addLongTaskWithStack:(NSString *)stack duration:(NSNumber *)duration property:(nullable NSDictionary *)property;
/// Add a freeze event
/// - Parameters:
///   - stack: The freeze stack trace
///   - duration: The freeze duration (nanoseconds)
///   - property: Custom attributes for the event (optional)
func addLongTask(withStack: String, duration: NSNumber, property: [AnyHashable : Any]?)

Code Examples

// Scenario 1
[[FTExternalDataManager sharedManager] addLongTaskWithStack:@"stack string" duration:@1000000000];
// Scenario 2: Dynamic parameters
[[FTExternalDataManager sharedManager] addLongTaskWithStack:@"stack string" duration:@1000000000 property:@{@"custom_key":@"custom_value"}];
// Scenario 1
FTExternalDataManager.shared().addLongTask(withStack: "stack string", duration: 1000000000)
// Scenario 2: Dynamic parameters
FTExternalDataManager.shared().addLongTask(withStack: "stack string", duration: 1000000000 ,property: [["custom_key":"custom_value"]])

Resource

Usage

/// Start an HTTP request
/// - Parameters:
///   - key: The request identifier
///   - property: Custom attributes for the event (optional)
- (void)startResourceWithKey:(NSString *)key property:(nullable NSDictionary *)property;

/// Add request data for HTTP
///
/// - Parameters:
///   - key: The request identifier
///   - metrics: Request-related performance metrics
///   - content: Request-related data
- (void)addResourceWithKey:(NSString *)key metrics:(nullable FTResourceMetricsModel *)metrics content:(FTResourceContentModel *)content;

/// End an HTTP request
/// - Parameters:
///   - key: The request identifier
///   - property: Custom attributes for the event (optional)
- (void)stopResourceWithKey:(NSString *)key property:(nullable NSDictionary *)property;
/// Start an HTTP request
/// - Parameters:
///   - key: The request identifier
///   - property: Custom attributes for the event (optional)
open func startResource(withKey key: String, property: [AnyHashable : Any]?)

/// End an HTTP request
/// - Parameters:
///   - key: The request identifier
///   - property: Custom attributes for the event (optional)
open func stopResource(withKey key: String, property: [AnyHashable : Any]?)

/// Add request data for HTTP
///
/// - Parameters:
///   - key: The request identifier
///   - metrics: Request-related performance metrics
///   - content: Request-related data
open func addResource(withKey key: String, metrics: FTResourceMetricsModel?, content: FTResourceContentModel)

Code Examples

// Step 1: Before the request starts
[[FTExternalDataManager sharedManager] startResourceWithKey:key];

// Step 2: After the request completes
[[FTExternalDataManager sharedManager] stopResourceWithKey:key];

// Step 3: Assemble Resource data
// FTResourceContentModel data
FTResourceContentModel *content = [[FTResourceContentModel alloc]init];
content.httpMethod = request.HTTPMethod;
content.requestHeader = request.allHTTPHeaderFields;
content.responseHeader = httpResponse.allHeaderFields;
content.httpStatusCode = httpResponse.statusCode;
content.responseBody = responseBody;
// iOS native
content.error = error;

// If timing data for each phase is available
// FTResourceMetricsModel
// For iOS native, use the NSURLSessionTaskMetrics data to initialize FTResourceMetricsModel
FTResourceMetricsModel *metricsModel = [[FTResourceMetricsModel alloc]initWithTaskMetrics:metrics];

// For other platforms, all time data is in nanoseconds
FTResourceMetricsModel *metricsModel = [[FTResourceMetricsModel alloc]init];

// Step 4: add resource. If there is no timing data, pass nil for metrics.
[[FTExternalDataManager sharedManager] addResourceWithKey:key metrics:metricsModel content:content];
// Step 1: Before the request starts
FTExternalDataManager.shared().startResource(withKey: key)

// Step 2: After the request completes
FTExternalDataManager.shared().stopResource(withKey: resource.key)

// Step 3: ① Assemble Resource data
let contentModel = FTResourceContentModel(request: task.currentRequest!, response: task.response as? HTTPURLResponse, data: resource.data, error: error)

// ② If timing data for each phase is available
// FTResourceMetricsModel
// For iOS native, use the NSURLSessionTaskMetrics data to initialize FTResourceMetricsModel
var metricsModel:FTResourceMetricsModel?
if let metrics = resource.metrics {
   metricsModel = FTResourceMetricsModel(taskMetrics:metrics)
}
// For other platforms, all time data is in nanoseconds
metricsModel = FTResourceMetricsModel()
...

// Step 4: add resource. If there is no timing data, pass nil for metrics.
FTExternalDataManager.shared().addResource(withKey: resource.key, metrics: metricsModel, content: contentModel)

Feedback

Is this page helpful?