macOS Application Integration¶
Guance application monitoring collects metric data from various macOS applications and visualizes the performance of each macOS application end.
Prerequisites¶
Note
If RUM Headless service is already activated, the prerequisites have been automatically configured. You can directly integrate your application.
- Install DataKit;
- Configure RUM collector
Application Integration¶
- Navigate to User Analysis > Create New Application > macOS;
- Enter the application name;
- Enter the application ID;
-
Choose the application integration method:
- Public DataWay: Directly receive RUM data without installing the DataKit collector.
- Local environment deployment: Receive RUM data after fulfilling the prerequisites.
Installation¶
Source Code Repository: https://github.com/GuanceCloud/datakit-macos
Demo: https://github.com/GuanceCloud/datakit-macos/Example
- Configure
Podfile
.
- Execute
pod install
in the directory wherePodfile
resides to install the SDK.
-
Select
PROJECT
->Package Dependency
, click on the + under thePackages
section. -
In the search box on the popped-up page, enter
https://github.com/GuanceCloud/datakit-macos
, which is the storage location of the code. -
After Xcode successfully fetches the package, it will display the SDK configuration page.
Dependency Rule
: It is recommended to select Up to Next Major Version
.
Add To Project
: Select the projects that need support.
Fill in the configuration and click the Add Package
button, wait for it to finish loading.
- In the pop-up window
Choose Package Products for datakit-macos
, select the Target to which you want to add the SDK, click theAdd Package
button. At this point, the SDK has been successfully added.
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 AppDelegate's applicationDidFinishLaunching
, to avoid abnormal collection of the first view's lifecycle, 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];
// Using public DataWay deployment
//FTSDKConfig *config = [[FTSDKConfig alloc]initWithDatawayUrl:datawayUrl clientToken:clientToken];
config.enableSDKDebugLog = YES;
[FTSDKAgent startWithConfigOptions:config];
}
return NSApplicationMain(argc, argv);
}
Create a main.swift file, delete @main or @NSApplicationMain in AppDelegate.swift
import Cocoa
import FTMacOSSDK
// Create AppDelegate and set it as the delegate
let delegate = AppDelegate()
NSApplication.shared.delegate = delegate
// Initialize SDK
let config = FTSDKConfig.init(datakitUrl: datakitUrl)
// Using 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 | Description |
---|---|---|---|
datakitUrl | NSString | Yes | Datakit access address, example: http://10.0.0.1:9529, default port 9529, devices installing SDK must be able to access this address. Note: choose one between datakit and dataway configurations |
datawayUrl | NSString | Yes | Public Dataway access address, example: http://10.0.0.1:9528, default port 9528, devices installing SDK must be able to access this address. Note: choose one between datakit and dataway configurations |
clientToken | NSString | Yes | Authentication token, must be used with datawayUrl |
enableSDKDebugLog | BOOL | No | Set whether to allow logging. Default NO |
env | NSString | No | Set the collection environment. Default prod , supports customization, or can be set via -setEnvWithType: method using the provided FTEnv enumeration |
service | NSString | No | Set the name of the business or service. Affects Log and RUM service field data. Default: df_rum_ios |
globalContext | NSDictionary | No | Add custom tags. For adding rules, please refer to 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 | Description |
---|---|---|---|
appid | NSString | Yes | Unique identifier for the User Analysis application ID. Corresponding to setting RUM appid , will enable RUM data collection function, 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 includes all View, Action, LongTask, Error data under the same session_id |
enableTrackAppCrash | BOOL | No | Set whether to collect crash logs. Default NO |
enableTrackAppANR | BOOL | No | Collect ANR lagging unresponsive events. Default NO |
enableTrackAppFreeze | BOOL | No | Collect UI freezing 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 rules. By default, no filtering. Return: NO means collect, YES means do not collect. |
errorMonitorType | FTErrorMonitorType | No | Additional error event monitoring types. Add monitoring information to collected crash data. FTErrorMonitorBattery indicates battery level, FTErrorMonitorMemory indicates memory usage, FTErrorMonitorCpu indicates CPU usage, default is none. |
monitorFrequency | FTMonitorFrequency | No | Performance monitoring sampling interval for views |
deviceMetricsMonitorType | FTDeviceMetricsMonitorType | No | Performance monitoring type for views. Adds corresponding monitoring item information to collected View data. FTDeviceMetricsMonitorMemory monitors current application memory usage, FTDeviceMetricsMonitorCpu monitors CPU spike count, FTDeviceMetricsMonitorFps monitors screen frame rate, default is none. |
globalContext | NSDictionary | No | Add custom tags to distinguish sources of user monitoring data. If tracking functionality is needed, parameter key should be track_id , value can be any value. For adding rules, please refer to 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 | Description |
---|---|---|---|
sampleRate | int | No | Sampling rate. Range [0,100], 0 means no collection, 100 means full collection, default is 100. |
enableCustomLog | BOOL | No | Whether to upload custom log. Default NO |
logLevelFilter | NSArray | No | Set status array of custom logs to collect. Default is all collected |
enableLinkRumData | BOOL | No | Whether to link with RUM data. Default NO |
discardType | FTLogCacheDiscard | No | Set log discard rule when limit is exceeded. Default FTDiscard When log data exceeds maximum (5000), discard appended data. FTDiscardOldest when log data exceeds maximum, discard old data. |
printCustomLogToConsole | BOOL | No | Whether to output custom logs to console. Default NO . Output format of custom logs here |
globalContext | NSDictionary | No | Add custom log tags. For adding rules, please refer to here |
Trace Configuration¶
Property | Type | Required | Description |
---|---|---|---|
sampleRate | int | No | Sampling rate. Range [0,100], 0 means no collection, 100 means full collection, default is 100. |
networkTraceType | NS_ENUM | No | Set the type of distributed tracing. Default is DDTrace , currently supports Zipkin , Jaeger , DDTrace , Skywalking (8.0+), TraceParent (W3C). When integrating OpenTelemetry, please check 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 tracing. Default NO , currently only supports NSURLSession |
RUM User Data Tracking¶
You can configure auto mode via FTRUMConfig
, or manually add. RUM-related data is passed through the FTGlobalRumManager
singleton instance. Relevant APIs are as follows:
View¶
If enableTraceUserView = YES
is set to enable auto-collection, the SDK will automatically collect Window lifecycles. The start of a View is defined by the Window lifecycle method -becomeKeyWindow
, and the end is defined by -resignKeyWindow
.
The page name is set based on priority order: NSStringFromClass(window.contentViewController.class)
> NSStringFromClass(window.windowController.class)
> NSStringFromClass(window)
.
If the view within the window is very complex, you can use the following API to customize collection.
Usage¶
/// Create Page
///
/// Call before `-startViewWithName` method. This method records page load time. If load time cannot be obtained, this method can be omitted.
/// - Parameters:
/// - viewName: Page name
/// - loadTime: Page load time (nanoseconds)
-(void)onCreateView:(NSString *)viewName loadTime:(NSNumber *)loadTime;
/// Enter Page
/// - Parameters:
/// - viewName: Page name
/// - property: Event custom properties (optional)
-(void)startViewWithName:(NSString *)viewName property:(nullable NSDictionary *)property;
/// Leave Page
/// - Parameter property: Event custom properties (optional)
-(void)stopViewWithProperty:(nullable NSDictionary *)property;
/// Create Page
///
/// Call before `-startViewWithName` method. This method records page load time. If load time cannot be obtained, this method can be omitted.
/// - Parameters:
/// - viewName: Page name
/// - loadTime: Page load time (ns)
open func onCreateView(_ viewName: String, loadTime: NSNumber)
/// Enter Page
/// - Parameters:
/// - viewName: Page name
/// - property: Event custom properties (optional)
open func startView(withName viewName: String, property: [AnyHashable : Any]?)
/// Leave Page
/// - Parameter property: Event custom properties (optional)
open func stopView(withProperty property: [AnyHashable : Any]?)
Example Code¶
- (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¶
Example Code¶
Error¶
Usage¶
/// Add Error Event
/// - Parameters:
/// - type: error type
/// - message: error message
/// - stack: stack trace
/// - property: event custom attributes (optional)
- (void)addErrorWithType:(NSString *)type message:(NSString *)message stack:(NSString *)stack property:(nullable NSDictionary *)property;
/// Add Error Event
/// - Parameters:
/// - type: error type
/// - state: program runtime state
/// - message: error message
/// - stack: stack trace
/// - property: event custom attributes (optional)
- (void)addErrorWithType:(NSString *)type state:(FTAppState)state message:(NSString *)message stack:(NSString *)stack property:(nullable NSDictionary *)property;
/// Add Error Event
/// - Parameters:
/// - type: error type
/// - message: error message
/// - stack: stack trace
/// - property: event custom attributes (optional)
open func addError(withType: String, message: String, stack: String, property: [AnyHashable : Any]?)
/// Add Error Event
/// - Parameters:
/// - type: error type
/// - state: program runtime state
/// - message: error message
/// - stack: stack trace
/// - property: event custom attributes (optional)
open func addError(withType type: String, state: FTAppState, message: String, stack: String, property: [AnyHashable : Any]?)
Example Code¶
// 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¶
Example Code¶
Resource¶
Usage¶
/// Start of HTTP request
/// - Parameters:
/// - key: Request identifier
/// - property: Event custom attributes (optional)
- (void)startResourceWithKey:(NSString *)key property:(nullable NSDictionary *)property;
/// Add request data for HTTP
///
/// - Parameters:
/// - key: Request identifier
/// - metrics: Performance properties related to the request
/// - content: Data related to the request
- (void)addResourceWithKey:(NSString *)key metrics:(nullable FTResourceMetricsModel *)metrics content:(FTResourceContentModel *)content;
/// End of HTTP request
/// - Parameters:
/// - key: Request identifier
/// - property: Event custom attributes (optional)
- (void)stopResourceWithKey:(NSString *)key property:(nullable NSDictionary *)property;
/// Start of HTTP request
/// - Parameters:
/// - key: Request identifier
/// - property: Event custom attributes (optional)
open func startResource(withKey key: String, property: [AnyHashable : Any]?)
/// End of HTTP request
/// - Parameters:
/// - key: Request identifier
/// - property: Event custom attributes (optional)
open func stopResource(withKey key: String, property: [AnyHashable : Any]?)
/// Add request data for HTTP
///
/// - Parameters:
/// - key: Request identifier
/// - metrics: Performance properties related to the request
/// - content: Data related to the request
open func addResource(withKey key: String, metrics: FTResourceMetricsModel?, content: FTResourceContentModel)
Example Code¶
#import "FTMacOSSDK.h"
// Step 1: Before request starts
[[FTGlobalRumManager sharedManager] startResourceWithKey:key];
// Step 2: 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 phase timing data can be obtained
// FTResourceMetricsModel
// For iOS native, if NSURLSessionTaskMetrics data is available, directly use the initialization method of FTResourceMetricsModel
FTResourceMetricsModel *metricsModel = [[FTResourceMetricsModel alloc]initWithTaskMetrics:metrics];
// For other platforms, all timing data is in nanoseconds
FTResourceMetricsModel *metricsModel = [[FTResourceMetricsModel alloc]init];
// Step 4: Add resource; if no timing data, pass nil for metrics
[[FTGlobalRumManager sharedManager] addResourceWithKey:key metrics:metricsModel content:content];
import FTMacOSSDK
// Step 1: Before request starts
FTGlobalRumManager.shared().startResource(withKey: key)
// Step 2: Request completes
FTGlobalRumManager.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 phase timing data can be obtained
// FTResourceMetricsModel
// For iOS native, if NSURLSessionTaskMetrics data is available, directly use the initialization method of FTResourceMetricsModel
var metricsModel:FTResourceMetricsModel?
if let metrics = resource.metrics {
metricsModel = FTResourceMetricsModel(taskMetrics:metrics)
}
// For other platforms, all timing data is in nanoseconds
metricsModel = FTResourceMetricsModel()
...
// Step 4: Add resource; if no timing data, pass nil for metrics
FTGlobalRumManager.shared().addResource(withKey: resource.key, metrics: metricsModel, content: contentModel)
Logger Logging¶
Currently, log content is limited to 30 KB, and exceeding characters will be truncated.
Usage¶
//
// FTLogger.h
// FTMacOSSDK
/// Add info-type custom log
/// - Parameters:
/// - content: Log content
/// - property: Custom attributes (optional)
-(void)info:(NSString *)content property:(nullable NSDictionary *)property;
/// Add warning-type custom log
/// - Parameters:
/// - content: Log content
/// - property: Custom attributes (optional)
-(void)warning:(NSString *)content property:(nullable NSDictionary *)property;
/// Add error-type custom log
/// - Parameters:
/// - content: Log content
/// - property: Custom attributes (optional)
-(void)error:(NSString *)content property:(nullable NSDictionary *)property;
/// Add critical-type custom log
/// - Parameters:
/// - content: Log content
/// - property: Custom attributes (optional)
-(void)critical:(NSString *)content property:(nullable NSDictionary *)property;
/// Add ok-type custom log
/// - Parameters:
/// - content: Log content
/// - property: Custom attributes (optional)
-(void)ok:(NSString *)content property:(nullable NSDictionary *)property;
open class FTLogger : NSObject, FTLoggerProtocol {}
public protocol FTLoggerProtocol : NSObjectProtocol {
/// Add info-type custom log
/// - Parameters:
/// - content: Log content
/// - property: Custom attributes (optional)
optional func info(_ content: String, property: [AnyHashable : Any]?)
/// Add warning-type custom log
/// - Parameters:
/// - content: Log content
/// - property: Custom attributes (optional)
optional func warning(_ content: String, property: [AnyHashable : Any]?)
/// Add error-type custom log
/// - Parameters:
/// - content: Log content
/// - property: Custom attributes (optional)
optional func error(_ content: String, property: [AnyHashable : Any]?)
/// Add critical-type custom log
/// - Parameters:
/// - content: Log content
/// - property: Custom attributes (optional)
optional func critical(_ content: String, property: [AnyHashable : Any]?)
/// Add ok-type custom log
/// - Parameters:
/// - content: Log content
/// - property: Custom attributes (optional)
optional func ok(_ content: String, property: [AnyHashable : Any]?)
}
Log Levels¶
Example Code¶
// Method 1: Through FTSDKAgent
// Note: Ensure the SDK has been initialized successfully when using, otherwise it will assert failure and crash in test environment.
[[FTSDKAgent sharedInstance] logging:@"test_custom" status:FTStatusInfo];
// Method 2: Through FTLogger (recommended)
// If the SDK hasn't been initialized successfully, calling methods in FTLogger to add custom logs will fail but won't cause an assertion failure crash.
[[FTLogger sharedInstance] info:@"test" property:@{@"custom_key":@"custom_value"}];
// Method 1: Through FTSDKAgent
// Note: Ensure the SDK has been initialized successfully when using, otherwise it will assert failure and crash in test environment.
FTSDKAgent.sharedInstance().logging("contentStr", status: .statusInfo, property:["custom_key":"custom_value"])
// Method 2: Through FTLogger (recommended)
// If the SDK hasn't been initialized successfully, calling methods in FTLogger to add custom logs will fail but won't cause an assertion failure crash.
FTLogger.shared().info("contentStr", property: ["custom_key":"custom_value"])
Custom Log Output to Console¶
Set printCustomLogToConsole = YES
to enable outputting custom logs to the console. You will see logs in the xcode debug console in the following format:
2023-06-29 13:47:56.960021+0800 App[64731:44595791]
: Standard prefix for os_log output;
[MACOS APP]
: Prefix used to distinguish custom logs output by the SDK;
[INFO]
: Level of the custom log;
content
: Content of the custom log;
{K=V,...,Kn=Vn}
: Custom attributes.
Trace Network Link Tracking¶
You can configure auto mode via FTTraceConfig
, or manually add. Trace-related data is passed through the FTTraceManager
singleton instance. Relevant APIs are as follows:
Usage¶
Example Code¶
NSString *key = [[NSUUID UUID]UUIDString];
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
// Manual operation required: Get traceHeader before request and add to 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 request and add to 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()
}
Binding and Unbinding Users¶
Usage¶
/// Bind user information
///
/// - Parameters:
/// - Id: User ID
/// - userName: User name (optional)
/// - userEmail: User email (optional)
/// - extra: Extra 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: Extra user information (optional)
open func bindUser(withUserID Id: String, userName: String?, userEmail: String?, extra: [AnyHashable : Any]?)
/// Unbind current user
open func unbindUser()
Example Code¶
// Can call this method after user login success 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}];
// Can call this method after user logout to unbind user information
[[FTSDKAgent sharedInstance] unbindUser];
// Can call this method after user login success 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])
// Can call this method after user logout to unbind user information
FTSDKAgent.sharedInstance().unbindUser()
Shut Down SDK¶
Use FTSDKAgent
to shut down the SDK.
Usage¶
Example Code¶
Add Custom Tags¶
Static Use¶
Multiple Configurations can be created using precompiled directives for setting values:
- Create multiple Configurations:
- Set preset properties to differentiate between different Configurations:
- Use precompiled directives:
//Target -> Build Settings -> GCC_PREPROCESSOR_DEFINITIONS for configuring 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 setup operations
[[FTSDKAgent sharedInstance] startRumWithConfigOptions:rumConfig];
Dynamic Use¶
Because settings made to globalContext after RUM has started will not take effect, users can save locally and apply them upon next app launch.
- Save locally via files, e.g.,
NSUserDefaults
, configure the use ofSDK
, and add code to retrieve tag data at the configuration point.
NSString *dynamicTag = [[NSUserDefaults standardUserDefaults] valueForKey:@"DYNAMIC_TAG"]?:@"NO_VALUE";
FTRumConfig *rumConfig = [[FTRumConfig alloc]init];
rumConfig.globalContext = @{@"dynamic_tag":dynamicTag};
... //Other setup operations
[[FTSDKAgent sharedInstance] startRumWithConfigOptions:rumConfig];
- Add a method to change file data anywhere.
- Restart the app to take effect.
Notes¶
-
Special key: track_id (configured in RUM, used for tracking functionality)
-
When a user adds a custom tag via globalContext that conflicts with an SDK-owned tag, the SDK’s tag will overwrite the user's setting. It is recommended to add a project abbreviation prefix to tag names, e.g.,
df_tag_name
. -
Setting globalContext before calling the -startRumWithConfigOptions method to start RUM is necessary for it to take effect.
-
Custom tags configured in
FTSDKConfig
will be added to all types of data.
For more detailed information, please refer to the SDK Demo.
Frequently Asked Questions¶
About Crash Log Analysis¶
Include of non-modular header inside framework module error occurs¶
Because the .h files of the SDK include dependent library .h files, the following needs to be set
Target
-> Build Settings
-> CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES
set to YES.好的,请提供需要继续翻译的内容。