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 | RUM application ID unique identifier. Corresponds to setting the RUM appid, which enables the RUM collection feature. How to get appid |
| sampleRate | int | No | Sampling rate. Range [0,100], 0 means no collection, 100 means full collection, default value is 100. Scope is all View, Action, LongTask, Error data under the same session_id |
| sessionOnErrorSampleRate | int | No | Set 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. Scope is all View, Action, LongTask, Error data under the same session_id. Supported from SDK 1.5.16 and above |
| 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. You can enable freeze collection and set the freeze threshold via -setEnableTrackAppFreeze:freezeDurationMs: method |
| freezeDurationMs | long | No | Set the UI freeze threshold. Range [100,), in milliseconds, default 250ms. Supported from SDK 1.5.7 and above |
| 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 applies to native HTTP. Note: Network requests initiated through [NSURLSession sharedSession] cannot collect performance data; SDK 1.5.9 and above support collecting network requests initiated via Swift's URLSession async/await APIs |
| resourceUrlHandler | FTResourceUrlHandler | No | Custom resource collection rules. Default no filtering. Return NO to collect, YES to not collect |
| errorMonitorType | FTErrorMonitorType | No | Supplementary error event monitoring type. Adds monitoring information to collected crash data. FTErrorMonitorBattery for battery level, FTErrorMonitorMemory for memory usage, FTErrorMonitorCpu for CPU usage, default not set |
| deviceMetricsMonitorType | FTDeviceMetricsMonitorType | No | View performance monitoring type, default not set. Adds corresponding monitoring information to collected View data. FTDeviceMetricsMonitorMemory monitors current app memory usage, FTDeviceMetricsMonitorCpu monitors CPU frequency, FTDeviceMetricsMonitorFps monitors screen frame rate |
| monitorFrequency | FTMonitorFrequency | No | View performance monitoring sampling period. FTMonitorFrequencyDefault 500ms (default), FTMonitorFrequencyFrequent 100ms, FTMonitorFrequencyRare 1000ms |
| enableResourceHostIP | BOOL | No | Whether to collect the IP 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 tracking functionality, the parameter key should be track_id, value can be any number. Please refer to here for adding rules |
| rumCacheLimitCount | int | No | Maximum RUM cache count. Default 100_000, supported from SDK 1.5.8 and above |
| rumDiscardType | FTRUMCacheDiscard | No | Set RUM discard rules. Default FTRUMCacheDiscard. FTRUMCacheDiscard discards appended data when RUM data exceeds the maximum; FTRUMDiscardOldest discards old data when RUM data exceeds the maximum. Supported from SDK 1.5.8 and above |
| resourcePropertyProvider | FTResourcePropertyProvider | No | Add custom RUM Resource properties via block callback. Supported from SDK 1.5.10 and above. Priority is lower than URLSession custom collection |
| enableTraceWebView | BOOL | No | Enable WebView data collection, default YES. Supported from SDK 1.5.17 and above |
| allowWebViewHost | NSArray | No | Set allowed WebView host addresses for data tracking. nil means collect all, default nil. Supported from SDK 1.5.17 and above |
| sessionTaskErrorFilter | FTSessionTaskErrorFilter | No | Whether to intercept URLSessionTask Error. Return YES to intercept, NO to not intercept. If intercepted, RUM-Error will not collect this error. Supported from SDK 1.5.17 and above |
| viewTrackingHandler | FTViewTrackingHandler | No | Custom View tracking logic to decide which ViewController should be monitored as a RUM View and set custom View Name. Prerequisite: enableTraceUserView = YES. Supported from SDK 1.5.18 and above, usage example here |
| swiftUIViewTrackingHandler | FTSwiftUIViewTrackingHandler | No | Experimental. Custom SwiftUI View auto-collection logic to filter auto-extracted SwiftUI View Names and customize RUM View Names. Prerequisite: enableTraceUserView = YES and this configuration is not empty. If no custom filtering or naming is needed, set FTDefaultSwiftUIViewTrackingHandler. This experimental API may be adjusted in future versions. Supported from SDK 1.6.4 and above, usage example here |
| actionTrackingHandler | FTActionTrackingHandler | No | Custom Action tracking logic to filter RUM Action events to record and customize Action Names. Prerequisite: enableTraceUserAction = YES. Supported from SDK 1.5.18 and above, usage example here |
| crashMonitoring | FTCrashMonitorType | No | Configure the type range of SDK crash monitoring. Default is FTCrashMonitorTypeHighCompatibility (high compatibility mode preset macro). Prerequisite: enableTrackAppCrash = YES. Note: FTCrashMonitorTypeSystem | FTCrashMonitorTypeApplicationState should be specified as they provide important information for reports. Supported from SDK 1.5.19 and above |
Sampling rate parameter naming
In SDK 1.6.6 and above, samplerate is deprecated. It can still be used and maps to the same value as sampleRate. New code should use sampleRate; versions below 1.6.6 should continue using samplerate.
RUM User Data Tracking¶
FTRUMConfig configures enableTraceUserAction, enableTraceUserView, enableTraceUserResource, enableTrackAppFreeze, enableTrackAppCrash, and enableTrackAppANR to achieve automatic collection and tracking of Action, View, Resource, LongTask, and Error data. If you want custom collection, you can report data through FTExternalDataManager.
View¶
Usage¶
/// Create a page
///
/// Called before the `-startViewWithName` method. This method records the page load time. If load time is not available, this method can be omitted.
/// - Parameters:
/// - viewName: Page name
/// - loadTime: Page load time (nanoseconds)
-(void)onCreateView:(NSString *)viewName loadTime:(NSNumber *)loadTime;
/// Enter a page
/// - Parameters:
/// - viewName: Page name
/// - property: Custom event attributes (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: Load duration (nanoseconds).
-(void)updateViewLoadingTime:(NSNumber *)duration;
/// Leave a page
/// - Parameter property: Custom event attributes (optional)
-(void)stopViewWithProperty:(nullable NSDictionary *)property;
/// Create a page
///
/// Called before the `-startViewWithName` method. This method records the page load time. If load time is not available, this method can be omitted.
/// - Parameters:
/// - viewName: Page name
/// - loadTime: Page load time (ns)
open func onCreateView(_ viewName: String, loadTime: NSNumber)
/// Enter a page
/// - Parameters:
/// - viewName: Page name
/// - property: Custom event attributes (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: Load duration (nanoseconds).
open func updateViewLoadingTime(_ duration: NSNumber)
/// Leave a page
/// - Parameter property: Custom event attributes (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 Manual Collection¶
SwiftUI View supports two collection methods:
- Automatic collection: Use
FTRumConfig.swiftUIViewTrackingHandlerto filter and name the SwiftUI View Names automatically extracted by the SDK. Suitable for scenarios where unified integration is desired with minimal business code changes. See SwiftUI View Automatic Collection. - Manual collection: Use
.ftTrackRUMView(name:property:)on specific SwiftUI Views to explicitly mark the start and end of a page. Suitable for scenarios where stable page names, precise control over View lifecycle, or auto-extracted names do not meet expectations.
Action¶
Usage¶
/// Start a RUM Action.
///
/// RUM will bind the Resource, Error, and LongTask events that may be triggered by this Action. Avoid adding multiple times within 0.1 seconds. The same View can only be associated with one Action at a time. If the previous Action has not ended, the new Action will be discarded.
/// This method does not conflict with `addAction:actionType:property` method.
///
/// - Parameters:
/// - actionName: Event name
/// - actionType: Event type
/// - property: Custom event attributes (optional)
- (void)startAction:(NSString *)actionName actionType:(NSString *)actionType property:(nullable NSDictionary *)property;
/// Add an Action event. No discard logic, does not bind Resource, Error, LongTask events.
///
/// Does not conflict with the RUM Action started by `startAction:actionType:property:`.
/// - Parameters:
/// - actionName: Event name
/// - actionType: Event type
/// - property: Custom event attributes (optional)
- (void)addAction:(NSString *)actionName actionType:(NSString *)actionType property:(nullable NSDictionary *)property;
/// Start a RUM Action.
///
/// RUM will bind the Resource, Error, and LongTask events that may be triggered by this Action. Avoid adding multiple times within 0.1 seconds. The same View can only be associated with one Action at a time. If the previous Action has not ended, the new Action will be discarded.
/// This method does not conflict with `addAction:actionType:property` method.
///
/// - Parameters:
/// - actionName: Event name
/// - actionType: Event type
/// - property: Custom event attributes (optional)
open func startAction(_ actionName: String, actionType: String, property: [AnyHashable : Any]?)
/// Add an Action event. No discard logic, does not bind Resource, Error, LongTask events.
///
/// Does not conflict with the RUM Action started by `startAction:actionType:property:`.
/// - Parameters:
/// - actionName: Event name
/// - actionType: Event type
/// - property: Custom event attributes (optional)
open func addAction(_ actionName: String, actionType: String, property: [AnyHashable : Any]?)
Code examples¶
SwiftUI Action Manual Collection¶
SwiftUI Action needs to be manually supplemented at business interaction points. For SwiftUI components such as Button, NavigationLink, List items, or custom gestures, actively record RUM Action at the location where the user operation is confirmed to have occurred.
SwiftUI Action supports two manual collection methods:
- Call within existing event closure: Use
FTRUMSwiftUI.trackTapAction(name:property:), which does not add extra gestures. Suitable forButton,NavigationLink,List, scroll views, or existing custom gesture scenarios. - Use View Modifier: Use
.ftTrackRUMTapAction(name:property:count:), which adds asimultaneousGestureto the current View. Suitable for simple tap collection on ordinary Views.
Note: If the same tap event has already been manually collected via
FTExternalDataManager, avoid using SwiftUI Action manual collection again to prevent duplicate reporting.
FTRUMSwiftUI.trackTapAction(name:property:) is the recommended manual collection method, especially suitable for components that already have tap closures. .ftTrackRUMTapAction(name:property:count:) is a convenient shorthand, but because it adds an extra tap gesture, it may affect existing interactions in List, NavigationLink, scroll containers, or complex gesture combinations. It is recommended to use FTRUMSwiftUI.trackTapAction(name:property:) within the existing tap closure instead.
Error¶
Usage¶
/// Add an Error event
/// - Parameters:
/// - type: Error type
/// - message: Error message
/// - stack: Stack trace
/// - property: Custom event attributes (optional)
- (void)addErrorWithType:(NSString *)type message:(NSString *)message stack:(NSString *)stack property:(nullable NSDictionary *)property;
/// Add an Error event
/// - Parameters:
/// - type: Error type
/// - state: App running state
/// - message: Error message
/// - stack: Stack trace
/// - property: Custom event attributes (optional)
- (void)addErrorWithType:(NSString *)type state:(FTAppState)state message:(NSString *)message stack:(NSString *)stack property:(nullable NSDictionary *)property;
/// Add an Error event
/// - Parameters:
/// - type: Error type
/// - message: Error message
/// - stack: Stack trace
/// - property: Custom event attributes (optional)
open func addError(withType: String, message: String, stack: String, property: [AnyHashable : Any]?)
/// Add an Error event
/// - Parameters:
/// - type: Error type
/// - state: App running state
/// - message: Error message
/// - stack: Stack trace
/// - property: Custom event attributes (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¶
Code examples¶
Resource¶
Usage¶
/// HTTP request start
/// - Parameters:
/// - key: Request identifier
/// - property: Custom event attributes (optional)
- (void)startResourceWithKey:(NSString *)key property:(nullable NSDictionary *)property;
/// HTTP add request data
///
/// - Parameters:
/// - key: Request identifier
/// - metrics: Request-related performance properties
/// - content: Request-related data
- (void)addResourceWithKey:(NSString *)key metrics:(nullable FTResourceMetricsModel *)metrics content:(FTResourceContentModel *)content;
/// HTTP request end
/// - Parameters:
/// - key: Request identifier
/// - property: Custom event attributes (optional)
- (void)stopResourceWithKey:(NSString *)key property:(nullable NSDictionary *)property;
/// HTTP request start
/// - Parameters:
/// - key: Request identifier
/// - property: Custom event attributes (optional)
open func startResource(withKey key: String, property: [AnyHashable : Any]?)
/// HTTP request end
/// - Parameters:
/// - key: Request identifier
/// - property: Custom event attributes (optional)
open func stopResource(withKey key: String, property: [AnyHashable : Any]?)
/// HTTP add request data
///
/// - Parameters:
/// - key: Request identifier
/// - metrics: Request-related performance properties
/// - content: Request-related data
open func addResource(withKey key: String, metrics: FTResourceMetricsModel?, content: FTResourceContentModel)
Code examples¶
// Step 1: Before request start
[[FTExternalDataManager sharedManager] startResourceWithKey:key];
// Step 2: Request completed
[[FTExternalDataManager sharedManager] stopResourceWithKey:key];
// Step 3: Construct 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 time data for each phase is available
// FTResourceMetricsModel
// For iOS native, use the initialization method of FTResourceMetricsModel directly with NSURLSessionTaskMetrics data
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 no time data, pass nil for metrics
[[FTExternalDataManager sharedManager] addResourceWithKey:key metrics:metricsModel content:content];
// Step 1: Before request start
FTExternalDataManager.shared().startResource(withKey: key)
// Step 2: Request completed
FTExternalDataManager.shared().stopResource(withKey: resource.key)
// Step 3: ① Construct Resource data
let contentModel = FTResourceContentModel(request: task.currentRequest!, response: task.response as? HTTPURLResponse, data: resource.data, error: error)
// ② If time data for each phase is available
// FTResourceMetricsModel
// For iOS native, use the initialization method of FTResourceMetricsModel directly with NSURLSessionTaskMetrics data
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 no time data, pass nil for metrics
FTExternalDataManager.shared().addResource(withKey: resource.key, metrics: metricsModel, content: contentModel)