macOS Application Integration¶
Guance application monitoring can collect metrics data from various macOS applications and analyze the performance of macOS application ends in a visualized manner.
Prerequisites¶
Note
If you have enabled the RUM Headless service, the prerequisites are automatically configured, and you can directly integrate the application.
- Install DataKit;
- Configure RUM Collector
Application Integration¶
- Go to User Analysis > Create > macOS;
- Enter the application name;
- Input the application ID;
-
Choose the application integration method:
- Public DataWay: Directly receives RUM data without installing the DataKit collector.
- Local Environment Deployment: Receives RUM data after meeting the prerequisites.
Installation¶
Source Code Address: https://github.com/GuanceCloud/datakit-macos
Demo: https://github.com/GuanceCloud/datakit-macos/Example
- Configure the
Podfile
.
- Run
pod install
in thePodfile
directory to install the SDK.
-
Select
PROJECT
->Package Dependency
, then click the + under thePackages
section. -
In the search box of the pop-up page, input
https://github.com/GuanceCloud/datakit-macos
, which is the storage location of the code. -
After Xcode successfully retrieves the package, it will display the configuration page for the SDK.
Dependency Rule
: It is recommended to choose Up to Next Major Version
.
Add To Project
: Select the supported project.
After filling in the configurations, click the Add Package
button and wait for the loading to complete.
- In the popup
Choose Package Products for datakit-macos
, select the Target where you need to add the SDK, and click theAdd Package
button. The SDK has been added successfully at this point.
If your project is managed by SPM, add FTMacOSSDK as a dependency and add dependencies
to Package.swift
.
Adding Header Files¶
SDK Initialization¶
Basic Configuration¶
Since the viewDidLoad
method of the first displayed view NSViewController
and the windowDidLoad
method of NSWindowController
are called earlier than the applicationDidFinishLaunching
method of AppDelegate, to avoid lifecycle collection anomalies for the first view, it is recommended to initialize the SDK in the main.m
file.
// main.m file
#import "FTMacOSSDK.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// Local environment deployment, Datakit deployment
FTSDKConfig *config = [[FTSDKConfig alloc]initWithDatakitUrl:datakitUrl];
// Use public DataWay deployment
//FTSDKConfig *config = [[FTSDKConfig alloc]initWithDatawayUrl:datawayUrl clientToken:clientToken];
config.enableSDKDebugLog = YES;
[FTSDKAgent startWithConfigOptions:config];
}
return NSApplicationMain(argc, argv);
}
Create a mian.swift file and delete @main or @NSApplicationMain in AppDelegate.swift.
import Cocoa
import FTMacOSSDK
// Create AppDelegate and set it as delegate
let delegate = AppDelegate()
NSApplication.shared.delegate = delegate
// Initialize SDK
let config = FTSDKConfig.init(datakitUrl: datakitUrl)
// Use public DataWay deployment
//let config = FTSDKConfig(datawayUrl: datawayUrl, clientToken: clientToken)
config.enableSDKDebugLog = true
FTSDKAgent.start(withConfigOptions: config)
_ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
Property | Type | Required | Meaning |
---|---|---|---|
datakitUrl | NSString | Yes | Datakit access address, example: http://10.0.0.1:9529, default port 9529, the device with the installed SDK must be able to access this address. Note: choose one between datakit and dataway configuration |
datawayUrl | NSString | Yes | Public Dataway access address, example: http://10.0.0.1:9528, default port 9528, the device with the installed SDK must be able to access this address. Note: choose one between datakit and dataway configuration |
clientToken | NSString | Yes | Authentication token, needs to be used together with datawayUrl |
enableSDKDebugLog | BOOL | No | Set whether to allow printing logs. Default NO |
env | NSString | No | Set the collection environment. Default prod , supports customization, can also be set using the provided FTEnv enumeration through the -setEnvWithType: method |
service | NSString | No | Set the name of the business or service that belongs. Affects Log and RUM service field data. Default: df_rum_ios |
globalContext | NSDictionary | No | Add custom tags. Refer to the rules here |
RUM Configuration¶
FTRumConfig *rumConfig = [[FTRumConfig alloc]initWithAppid:appid];
rumConfig.enableTrackAppCrash = YES;
rumConfig.enableTrackAppANR = YES;
rumConfig.enableTrackAppFreeze = YES;
rumConfig.enableTraceUserAction = YES;
rumConfig.enableTraceUserVIew = YES;
rumConfig.enableTraceUserResource = YES;
rumConfig.errorMonitorType = FTErrorMonitorAll;
rumConfig.deviceMetricsMonitorType = FTDeviceMetricsMonitorAll;
[[FTSDKAgent sharedInstance] startRumWithConfigOptions:rumConfig];
let rumConfig = FTRumConfig(appid: appid)
rumConfig.enableTraceUserAction = true
rumConfig.enableTrackAppANR = true
rumConfig.enableTraceUserView = true
rumConfig.enableTraceUserResource = true
rumConfig.enableTrackAppCrash = true
rumConfig.enableTrackAppFreeze = true
rumConfig.errorMonitorType = .all
rumConfig.deviceMetricsMonitorType = .all
rumConfig.monitorFrequency = .rare
FTSDKAgent.sharedInstance().startRum(withConfigOptions: rumConfig)
Property | Type | Required | Meaning |
---|---|---|---|
appid | NSString | Yes | User access monitoring application ID unique identifier. Corresponds to setting the RUM appid , only then will the RUM collection function be enabled, method to obtain appid |
sampleRate | int | No | Sampling rate. Range [0,100], 0 means no collection, 100 means full collection, default value is 100. Scope includes all View, Action, LongTask, Error data under the same session_id |
enableTrackAppCrash | BOOL | No | Set whether crash logs need to be collected. Default NO |
enableTrackAppANR | BOOL | No | Collect ANR events where the app freezes and does not respond. Default NO |
enableTrackAppFreeze | BOOL | No | Collect UI freeze events. Default NO |
enableTraceUserView | BOOL | No | Set whether to track user View operations. Default NO |
enableTraceUserAction | BOOL | No | Set whether to track user Action operations. Default NO |
enableTraceUserResource | BOOL | No | Set whether to track user network requests. Default NO , only applies to native http |
resourceUrlHandler | FTResourceUrlHandler | No | Custom resource collection rule. Default does not filter. Returns: NO indicates to collect, YES indicates not to collect. |
errorMonitorType | FTErrorMonitorType | No | Supplementary type for error event monitoring. Adds monitored information to the collected crash data. FTErrorMonitorBattery for battery level, FTErrorMonitorMemory for memory usage, FTErrorMonitorCpu for CPU occupancy rate. |
monitorFrequency | FTMonitorFrequency | No | Performance monitoring sampling cycle for views |
deviceMetricsMonitorType | FTDeviceMetricsMonitorType | No | Performance monitoring type for views. Adds corresponding monitored items to the collected View data. FTDeviceMetricsMonitorMemory monitors current application memory usage, FTDeviceMetricsMonitorCpu monitors CPU fluctuations, FTDeviceMetricsMonitorFps monitors screen frame rate. |
globalContext | NSDictionary | No | Add custom tags for user monitoring data source distinction. If tracking functionality is needed, the parameter key should be track_id , value should be any number, refer to the notes on adding rules here |
Log Configuration¶
// Enable logger
FTLoggerConfig *loggerConfig = [[FTLoggerConfig alloc]init];
loggerConfig.enableCustomLog = YES;
loggerConfig.printCustomLogToConsole = YES;
loggerConfig.enableLinkRumData = YES;
loggerConfig.logLevelFilter = @[@(FTStatusError),@(FTStatusCritical)];
loggerConfig.discardType = FTDiscardOldest;
[[FTSDKAgent sharedInstance] startLoggerWithConfigOptions:loggerConfig];
let loggerConfig = FTLoggerConfig()
loggerConfig.enableCustomLog = true
loggerConfig.enableLinkRumData = true
loggerConfig.printCustomLogToConsole = true
loggerConfig.logLevelFilter = [NSNumber(value: FTLogStatus.statusError.rawValue),NSNumber(value: FTLogStatus.statusCritical.rawValue)] // loggerConfig.logLevelFilter = [2,3]
loggerConfig.discardType = .discardOldest
FTSDKAgent.sharedInstance().startLogger(withConfigOptions: loggerConfig)
Property | Type | Required | Meaning |
---|---|---|---|
sampleRate | int | No | Sampling rate. Range [0,100], 0 means no collection, 100 means full collection, default value is 100. |
enableCustomLog | BOOL | No | Whether to upload custom logs. Default NO |
logLevelFilter | NSArray | No | Set the status array for the custom logs to be collected. Default collects all. |
enableLinkRumData | BOOL | No | Whether to link with RUM data. Default NO |
discardType | FTLogCacheDiscard | No | Set the log discard rule when reaching the limit. Default FTDiscard FTDiscard discards appended data when log data quantity exceeds the maximum (5000). FTDiscardOldest discards old data when log data exceeds the maximum. |
printCustomLogToConsole | BOOL | No | Set whether to output custom logs to the console. Default NO , refer to the output format for custom logs |
globalContext | NSDictionary | No | Add custom tags for logs, refer to the rules here |
Trace Configuration¶
Property | Type | Required | Meaning |
---|---|---|---|
sampleRate | int | No | Sampling rate. Range [0,100], 0 means no collection, 100 means full collection, default value is 100. |
networkTraceType | NS_ENUM | No | Set the type of trace. Default is DDTrace , currently supports Zipkin , Jaeger , DDTrace , Skywalking (8.0+), TraceParent (W3C), if choosing the corresponding trace type when integrating OpenTelemetry, please refer to the supported types and agent related configurations |
enableLinkRumData | BOOL | No | Whether to link with RUM data. Default NO |
enableAutoTrace | BOOL | No | Set whether to enable automatic http trace. Default NO , currently only supports NSURLSession |
RUM User Data Tracking¶
You can configure FTRUMConfig
to enable automatic mode or manually add data. Rum-related data is passed via the FTGlobalRumManager
singleton, with relevant APIs as follows:
View¶
If you set enableTraceUserView = YES
to enable automatic collection, the SDK will automatically collect the lifecycle of the Window. The window's lifecycle -becomeKeyWindow
defines the start of the View, and -resignKeyWindow
defines the end of the View.
The page name is set according to the priority order: NSStringFromClass(window.contentViewController.class)
> NSStringFromClass(window.windowController.class)
> NSStringFromClass(window)
.
If the views within the window are very complex, you can use the following API to customize the collection.
Usage Method¶
/// Create a page
///
/// Call before the `-startViewWithName` method. This method records the page loading time; if the loading time cannot be obtained, this method can be omitted.
/// - Parameters:
/// - viewName: Page name
/// - loadTime: Page loading time (nanoseconds)
-(void)onCreateView:(NSString *)viewName loadTime:(NSNumber *)loadTime;
/// Enter the page
/// - Parameters:
/// - viewName: Page name
/// - property: Event custom properties (optional)
-(void)startViewWithName:(NSString *)viewName property:(nullable NSDictionary *)property;
/// Leave the page
/// - Parameter property: Event custom properties (optional)
-(void)stopViewWithProperty:(nullable NSDictionary *)property;
/// Create a page
///
/// Call before the `-startViewWithName` method. This method records the page loading time; if the loading time cannot be obtained, this method can be omitted.
/// - Parameters:
/// - viewName: Page name
/// - loadTime: Page loading time (ns)
open func onCreateView(_ viewName: String, loadTime: NSNumber)
/// Enter the page
/// - Parameters:
/// - viewName: Page name
/// - property: Event custom properties (optional)
open func startView(withName viewName: String, property: [AnyHashable : Any]?)
/// Leave the page
/// - Parameter property: Event custom properties (optional)
open func stopView(withProperty property: [AnyHashable : Any]?)
Code Example¶
- (void)viewDidAppear{
[super viewDidAppear];
// Scenario 1:
[[FTGlobalRumManager sharedManager] startViewWithName:@"TestVC"];
// Scenario 2: Dynamic parameters
[[FTGlobalRumManager sharedManager] startViewWithName:@"TestVC" property:@{@"custom_key":@"custom_value"}];
}
-(void)viewDidDisappear{
[super viewDidDisappear];
// Scenario 1:
[[FTGlobalRumManager sharedManager] stopView];
// Scenario 2: Dynamic parameters
[[FTGlobalRumManager sharedManager] stopViewWithProperty:@{@"custom_key":@"custom_value"}];
}
override func viewDidAppear() {
super.viewDidAppear()
// Scenario 1:
FTExternalDataManager.shared().startView(withName: "TestVC")
// Scenario 2: Dynamic parameters
FTExternalDataManager.shared().startView(withName: "TestVC",property: ["custom_key":"custom_value"])
}
override func viewDidDisappear() {
super.viewDidDisappear()
// Scenario 1:
FTGlobalRumManager.shared().stopView()
// Scenario 2: Dynamic parameters
FTGlobalRumManager.shared().stopView(withProperty: ["custom_key":"custom_value"])
}
Action¶
Usage Method¶
Code Example¶
Error¶
Usage Method¶
/// Add an Error event
/// - Parameters:
/// - type: Error type
/// - message: Error message
/// - stack: Stack trace
/// - property: Event custom properties (optional)
- (void)addErrorWithType:(NSString *)type message:(NSString *)message stack:(NSString *)stack property:(nullable NSDictionary *)property;
/// Add an Error event
/// - Parameters:
/// - type: Error type
/// - state: Program runtime state
/// - message: Error message
/// - stack: Stack trace
/// - property: Event custom properties (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: Event custom properties (optional)
open func addError(withType: String, message: String, stack: String, property: [AnyHashable : Any]?)
/// Add an Error event
/// - Parameters:
/// - type: Error type
/// - state: Program runtime state
/// - message: Error message
/// - stack: Stack trace
/// - property: Event custom properties (optional)
open func addError(withType type: String, state: FTAppState, message: String, stack: String, property: [AnyHashable : Any]?)
Code Example¶
// Scenario 1
[[FTGlobalRumManager sharedManager] addErrorWithType:@"type" message:@"message" stack:@"stack"];
// Scenario 2: Dynamic parameters
[[FTGlobalRumManager sharedManager] addErrorWithType:@"ios_crash" message:@"crash_message" stack:@"crash_stack" property:@{@"custom_key":@"custom_value"}];
// Scenario 3: Dynamic parameters
[[FTGlobalRumManager sharedManager] addErrorWithType:@"ios_crash" state:FTAppStateUnknown message:@"crash_message" stack:@"crash_stack" property:@{@"custom_key":@"custom_value"}];
// Scenario 1
FTGlobalRumManager.shared().addError(withType: "custom_type", message: "custom_message", stack: "custom_stack")
// Scenario 2: Dynamic parameters
FTGlobalRumManager.shared().addError(withType: "custom_type", message: "custom_message", stack: "custom_stack",property: ["custom_key":"custom_value"])
// Scenario 3: Dynamic parameters
FTGlobalRumManager.shared().addError(withType: "custom_type", state: .unknown, message: "custom_message", stack: "custom_stack", property: ["custom_key":"custom_value"])
LongTask¶
Usage Method¶
/// Add a long task event
/// - Parameters:
/// - stack: Long task stack
/// - duration: Duration of the long task (nanoseconds)
/// - property: Event custom properties (optional)
- (void)addLongTaskWithStack:(NSString *)stack duration:(NSNumber *)duration property:(nullable NSDictionary *)property;
Code Example¶
Resource¶
Usage Method¶
/// Start HTTP request
/// - Parameters:
/// - key: Request identifier
/// - property: Event custom properties (optional)
- (void)startResourceWithKey:(NSString *)key property:(nullable NSDictionary *)property;
/// Add HTTP request data
///
/// - Parameters:
/// - key: Request identifier
/// - metrics: Request performance attributes
/// - content: Request related data
- (void)addResourceWithKey:(NSString *)key metrics:(nullable FTResourceMetricsModel *)metrics content:(FTResourceContentModel *)content;
/// End HTTP request
/// - Parameters:
/// - key: Request identifier
/// - property: Event custom properties (optional)
- (void)stopResourceWithKey:(NSString *)key property:(nullable NSDictionary *)property;
/// Start HTTP request
/// - Parameters:
/// - key: Request identifier
/// - property: Event custom properties (optional)
open func startResource(withKey key: String, property: [AnyHashable : Any]?)
/// End HTTP request
/// - Parameters:
/// - key: Request identifier
/// - property: Event custom properties (optional)
open func stopResource(withKey key: String, property: [AnyHashable : Any]?)
/// Add HTTP request data
///
/// - Parameters:
/// - key: Request identifier
/// - metrics: Request performance attributes
/// - content: Request related data
open func addResource(withKey key: String, metrics: FTResourceMetricsModel?, content: FTResourceContentModel)
Code Example¶
#import "FTMacOSSDK.h"
// Step 1: Before the request starts
[[FTGlobalRumManager sharedManager] startResourceWithKey:key];
// Step 2: When the request completes
[[FTGlobalRumManager 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 time data for each stage can be obtained
// FTResourceMetricsModel
// For ios native, if NSURLSessionTaskMetrics data is available, use the initializer method of FTResourceMetricsModel
FTResourceMetricsModel *metricsModel = [[FTResourceMetricsModel alloc]initWithTaskMetrics:metrics];
// For other platforms, all time data should be in nanoseconds
FTResourceMetricsModel *metricsModel = [[FTResourceMetricsModel alloc]init];
// Step 4: Add resource, pass nil for metrics if there is no time data
[[FTGlobalRumManager sharedManager] addResourceWithKey:key metrics:metricsModel content:content];
import FTMacOSSDK
// Step 1: Before the request starts
FTGlobalRumManager.shared().startResource(withKey: key)
// Step 2: When the request completes
FTGlobalRumManager.shared().stopResource(withKey: resource.key)
// Step 3: Assemble Resource data
// FTResourceContentModel
let contentModel = FTResourceContentModel(request: task.currentRequest!, response: task.response as? HTTPURLResponse, data: resource.data, error: error)
// If time data for each stage can be obtained
// FTResourceMetricsModel
// For ios native, if NSURLSessionTaskMetrics data is available, use the initializer method of FTResourceMetricsModel
var metricsModel:FTResourceMetricsModel?
if let metrics = resource.metrics {
metricsModel = FTResourceMetricsModel(taskMetrics:metrics)
}
// For other platforms, all time data should be in nanoseconds
metricsModel = FTResourceMetricsModel()
...
// Step 4: Add resource, pass nil for metrics if there is no time data
FTGlobalRumManager.shared().addResource(withKey: resource.key, metrics: metricsModel, content: contentModel)
Logger Log Printing¶
Currently, the log content is limited to 30 KB, and any characters exceeding this limit will be truncated.
Usage Method¶
//
// FTLogger.h
// FTMacOSSDK
/// Add custom info logs
/// - Parameters:
/// - content: Log content
/// - property: Custom properties (optional)
-(void)info:(NSString *)content property:(nullable NSDictionary *)property;
/// Add custom warning logs
/// - Parameters:
/// - content: Log content
/// - property: Custom properties (optional)
-(void)warning:(NSString *)content property:(nullable NSDictionary *)property;
/// Add custom error logs
/// - Parameters:
/// - content: Log content
/// - property: Custom properties (optional)
-(void)error:(NSString *)content property:(nullable NSDictionary *)property;
/// Add custom critical logs
/// - Parameters:
/// - content: Log content
/// - property: Custom properties (optional)
-(void)critical:(NSString *)content property:(nullable NSDictionary *)property;
/// Add custom ok logs
/// - Parameters:
/// - content: Log content
/// - property: Custom properties (optional)
-(void)ok:(NSString *)content property:(nullable NSDictionary *)property;
open class FTLogger : NSObject, FTLoggerProtocol {}
public protocol FTLoggerProtocol : NSObjectProtocol {
/// Add custom info logs
/// - Parameters:
/// - content: Log content
/// - property: Custom properties (optional)
optional func info(_ content: String, property: [AnyHashable : Any]?)
/// Add custom warning logs
/// - Parameters:
/// - content: Log content
/// - property: Custom properties (optional)
optional func warning(_ content: String, property: [AnyHashable : Any]?)
/// Add custom error logs
/// - Parameters:
/// - content: Log content
/// - property: Custom properties (optional)
optional func error(_ content: String, property: [AnyHashable : Any]?)
/// Add custom critical logs
/// - Parameters:
/// - content: Log content
/// - property: Custom properties (optional)
optional func critical(_ content: String, property: [AnyHashable : Any]?)
/// Add custom ok logs
/// - Parameters:
/// - content: Log content
/// - property: Custom properties (optional)
optional func ok(_ content: String, property: [AnyHashable : Any]?)
}
Log Levels¶
Code Example¶
// Method one: Through FTSDKAgent
// Note: Ensure the SDK is initialized successfully before use, otherwise it may fail assertion and crash in test environments.
[[FTSDKAgent sharedInstance] logging:@"test_custom" status:FTStatusInfo];
// Method two: Through FTLogger (recommended)
// If the SDK fails initialization, calling methods in FTLogger to add custom logs will fail but won't cause assertion failure or crash.
[[FTLogger sharedInstance] info:@"test" property:@{@"custom_key":@"custom_value"}];
// Method one: Through FTSDKAgent
// Note: Ensure the SDK is initialized successfully before use, otherwise it may fail assertion and crash in test environments.
FTSDKAgent.sharedInstance().logging("contentStr", status: .statusInfo, property:["custom_key":"custom_value"])
// Method two: Through FTLogger (recommended)
// If the SDK fails initialization, calling methods in FTLogger to add custom logs will fail but won't cause assertion failure or crash.
FTLogger.shared().info("contentStr", property: ["custom_key":"custom_value"])
Custom Logs Output to Console¶
Set printCustomLogToConsole = YES
to enable outputting custom logs to the console. You will see logs in the following format in the xcode debug console:
2023-06-29 13:47:56.960021+0800 App[64731:44595791]
: Standard prefix for os_log output;
[MACOS APP]
: Prefix to distinguish SDK custom log output;
[INFO]
: Level of the custom log;
content
: Content of the custom log;
{K=V,...,Kn=Vn}
: Custom properties.
Trace Network Link Tracing¶
You can configure FTTraceConfig
to enable automatic mode or manually add data. Trace-related data is passed via the FTTraceManager
singleton, with relevant APIs as follows:
Usage Method¶
Code Example¶
NSString *key = [[NSUUID UUID]UUIDString];
NSURL *url = [NSURL URLWithString:@"http://wwwbaidu.com"];
// Manual operation required: Get traceHeader before the request and add it to the request headers
NSDictionary *traceHeader = [[FTTraceManager sharedInstance] getTraceHeaderWithKey:key url:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
if (traceHeader && traceHeader.allKeys.count>0) {
[traceHeader enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) {
[request setValue:value forHTTPHeaderField:field];
}];
}
NSURLSession *session=[NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// Your code
}];
[task resume];
let url:URL = NSURL.init(string: "https://www.baidu.com")! as URL
if let traceHeader = FTTraceManager.sharedInstance().getTraceHeader(withKey: NSUUID().uuidString, url: url) {
let request = NSMutableURLRequest(url: url)
// Manual operation required: Get traceHeader before the request and add it to the request headers
for (a,b) in traceHeader {
request.setValue(b as? String, forHTTPHeaderField: a as! String)
}
let task = URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in
// Your code
}
task.resume()
}
User Binding and Logout¶
Usage Method¶
/// Bind user information
///
/// - Parameters:
/// - Id: User ID
/// - userName: User name (optional)
/// - userEmail: User email (optional)
/// - extra: Additional user information (optional)
- (void)bindUserWithUserID:(NSString *)Id userName:(nullable NSString *)userName userEmail:(nullable NSString *)userEmail extra:(nullable NSDictionary *)extra;
/// Unbind current user
- (void)unbindUser;
/// Bind user information
///
/// - Parameters:
/// - Id: User ID
/// - userName: User name (optional)
/// - userEmail: User email (optional)
/// - extra: Additional user information (optional)
open func bindUser(withUserID Id: String, userName: String?, userEmail: String?, extra: [AnyHashable : Any]?)
/// Unbind current user
open func unbindUser()
Code Example¶
// You can call this method after a successful user login to bind user information
[[FTSDKAgent sharedInstance] bindUserWithUserID:USERID];
// or
[[FTSDKAgent sharedInstance] bindUserWithUserID:USERID userName:USERNAME userEmail:USEREMAIL];
// or
[[FTSDKAgent sharedInstance] bindUserWithUserID:USERID userName:USERNAME userEmail:USEREMAIL extra:@{EXTRA_KEY:EXTRA_VALUE}];
// You can call this method after the user logs out to unbind user information
[[FTSDKAgent sharedInstance] unbindUser];
// You can call this method after a successful user login to bind user information
FTSDKAgent.sharedInstance().bindUser(withUserID: USERID)
// or
FTSDKAgent.sharedInstance().bindUser(withUserID: USERID, userName: USERNAME, userEmail: USEREMAIL)
// or
FTSDKAgent.sharedInstance().bindUser(withUserID: USERID, userName: USERNAME, userEmail: USEREMAIL,extra:[EXTRA_KEY:EXTRA_VALUE])
// You can call this method after the user logs out to unbind user information
FTSDKAgent.sharedInstance().unbindUser()
Shut Down SDK¶
Use FTSDKAgent
to shut down the SDK.
Usage Method¶
Code Example¶
Add Custom Tags¶
Static Use¶
You can create multiple Configurations and use preprocessor directives to set values:
- Create multiple Configurations:
- Set preset attributes to distinguish different Configurations:
- Use preprocessor directives:
// Target -> Build Settings -> GCC_PREPROCESSOR_DEFINITIONS configure preset definitions
#if PRE
#define Track_id @"0000000001"
#define STATIC_TAG @"preprod"
#elif DEVELOP
#define Track_id @"0000000002"
#define STATIC_TAG @"common"
#else
#define Track_id @"0000000003"
#define STATIC_TAG @"prod"
#endif
FTRumConfig *rumConfig = [[FTRumConfig alloc]init];
rumConfig.globalContext = @{@"track_id":Track_id,@"static_tag":STATIC_TAG};
... // other setting operations
[[FTSDKAgent sharedInstance] startRumWithConfigOptions:rumConfig];
Dynamic Use¶
Since globalContext settings made after RUM starts will not take effect, users can save them locally and set them during the next app launch.
- Save files locally using, for example,
NSUserDefaults
, and configure theSDK
. Add code to obtain tag data at the configuration location.
NSString *dynamicTag = [[NSUserDefaults standardUserDefaults] valueForKey:@"DYNAMIC_TAG"]?:@"NO_VALUE";
FTRumConfig *rumConfig = [[FTRumConfig alloc]init];
rumConfig.globalContext = @{@"dynamic_tag":dynamicTag};
... // other setting operations
[[FTSDKAgent sharedInstance] startRumWithConfigOptions:rumConfig];
- Add methods to change file data anywhere.
- Restart the application for the changes to take effect.
Notes¶
-
Special key: track_id (configured in RUM for tracking functionality)
-
When users add custom tags via globalContext that conflict with SDK's own tags, the SDK's tags will override the user's settings. It is recommended to prefix tag names with project abbreviations, such as
df_tag_name
. -
The globalContext must be set before calling the -startRumWithConfigOptions method to take effect.
-
Custom tags configured in
FTSDKConfig
will be added to all types of data.
For more detailed information, refer to the SDK Demo.
Frequently Asked Questions¶
About Crash Log Analysis¶
Error Occurs: Include of non-modular header inside framework module¶
Because the .h files in the SDK import dependent library .h files, you need to set
Target
-> Build Settings
-> CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES
to YES.