Versions Compared

    Key

    • This line was added.
    • This line was removed.
    • Formatting was changed.
    Comment: Published by Scroll Versions from this space and version 20.6
    Sv translation
    languageen
    Appd tocbox
    Width225px

    Related pages:

    Once you have instrumented your iOS application with the Mobile iOS SDK, you can also use the APIs exposed by the SDK to customize the data for your app that appears in the Controller UI.

    Info

    Because the agent stores data about events in a local buffer before reporting the information, you are recommended to use the APIs with discretion.

    Collect Additional Types of Data

    You can use methods available in the ADEUMInstrumentation class to collect six additional types of data:

    Type of DataDescriptionSpecificationsWhere Data is Displayed
    Info pointsHow often a method is invoked, and how long it takes to run.
    • Data is numeric
    • Names must consist of
      alphanumeric characters and/or spaces
    Custom timersAny arbitrary sequence of events within your code timed,
    even spanning multiple methods.
    • Data is numeric
    • Metric names must consist of
      alphanumeric characters and/or spaces
    Custom metricsAny integer-based data you wish to collect.
    • Data is numeric
    • Metric names must consist of
      alphanumeric characters and/or spaces
    User dataAny string key/value pair you think might be useful.
    • Data can be any type
    • Metric names have no restrictions
    BreadcrumbsThe context for a crash.
    • Data can be any data type
    • Metric names have no restrictions
    User interactionCapture when users press buttons, click on lists, and select text.
    • Data can be any data type
    • Metric names have no restrictions
    Info

    When you have set up additional data types, the Mobile Agent packages that data in a mobile beacon. Normally, the beacon is transmitted when the instrumented app sends an HTTP request or when the app is restarted following a crash, but if custom data has been collected and neither of those events has occurred for at least five minutes, the custom data is sent at that time.

    Anchor
    InfPt
    InfPt
    Info Points

    Information points allow you to track how your own code is running. You can see how often a method is invoked, and how long it takes to run, by using beginCall and endCall, something like the following:

    Tabs Container
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    - (void)myMethod
        {
            id tracker = [ADEumInstrumentation beginCall:self selector:_cmd];
    
            // Implementation of method here ...
    
            [ADEumInstrumentation endCall:tracker];
        }
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    func myMethod() {
        let tracker = ADEumInstrumentation.beginCall(self, selector: #function)
        // Implementation of method here ...
        ADEumInstrumentation.endCall(tracker)
    }

    If an exception is thrown, it is also reported. This information appears in the Custom Data view in the Controller UI.  

    Anchor
    CusTim
    CusTim
    Custom Timers

    Custom timers allow you to time any arbitrary sequence of events within your code, even spanning multiple methods, by using startTimer and stopTimer. For example, to track the time a user spends viewing a screen, the instrumentation could look like this:

    Tabs Container
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    - (void)viewDidAppear:(BOOL)animated {
          [super viewDidAppear:animated];
          [ADEumInstrumentation startTimerWithName:@"View Lifetime"];
      }
    - (void)viewDidDisappear:(BOOL)animated {
          [super viewDidDisappear:animated];
          [ADEumInstrumentation stopTimerWithName:@"View Lifetime"];
      }
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        ADEumInstrumentation.startTimer(withName: "View Lifetime")
    }
    func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        ADEumInstrumentation.stopTimer(withName: "View Lifetime")
    }


    This information appears in the Custom Data view of the Controller UI.

    Info

    Calling startTimerWithName again with the same name value resets a named timer.

    Anchor
    CusMet
    CusMet
    Custom Metrics

    Any integer-based data can be passed to the agent. The first parameter to the report.MetricWithName call is the name you want the metric to appear under in the Controller UI. The metric name should only contain alphanumeric characters and spaces. Illegal characters are replaced by their ASCII hex value.

    Reporting a metric called "My custom metric", for example, would look something like this:

    Code Block
    [ADEumInstrumentation reportMetricWithName:@"My custom metric" value:<#VALUE HERE#>];

    This information appears in the Custom Data view of the Controller UI.

    Anchor
    udata
    udata
    User Data

    You can set any string key/value pair you think might be useful. The first parameter to the setUserData call is the key you want to use, which must be unique across your application. The second is the value that you want to be assigned to the key.

    For example: 

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    - (void) onUserLoggedIn:(NSString *)userid { 
        [ADEumInstrumentation setUserData:@"User ID" value:userid];
        ...
      }
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    func onUserLogged(in userid: String?) {
        ADEumInstrumentation.setUserData("User ID", value: userid)
    }

    This information is available in Network Request Analyze and is added to any crash snapshots that may be taken. Keys and values are limited to 2048 characters each. 

    You can also set user data with values of other types (Long, Boolean, Double, Date) using the following methods:

    Anchor
    iosbread
    iosbread
    Breadcrumbs

    Breadcrumbs allow you to situate a crash in the context of your user's experience. Set a breadcrumb when something interesting happens. If your application crashes at some point in the future, the breadcrumb will be displayed along with the crash report.

    There are two ways of leaving breadcrumbs:

    Anchor
    nor1
    nor1
    Using this method means that breadcrumbs are reported in crash reports only.

    Code Block
    + (void)leaveBreadcrumb:(NSString *)breadcrumb
    Anchor
    mod1
    mod1
    Using this method lets you fine tune where the breadcrumbs are reported, either only in crash reports or in crash reports and sessions.
    Code Block
    + (void)leaveBreadcrumb:(NSString *)breadcrumb mode:(ADEumBreadcrumbVisibility)mode

    Where mode is either:

    • ADEumBreadcrumbVisibilityCrashesOnly
    • ADEumBreadcrumbVisibilityCrashesAndSessions
    Info

    If the breadcrumb is over 2048 characters, it is truncated. If it is empty or nil, no breadcrumb is recorded. Each crash report displays the most recent 99 breadcrumbs.


    Anchor
    crashreport
    crashreport
    Add a Crash Reporting Callback

    You may want to make crash report information that Mobile RUM collects available to other parts of your code, for example, to Google Analytics, if you are using it. To enable you to pass on summary crash information, you can set up a crash report runtime callback. To get a callback when the iOS Agent detects and then reports a crash, you need to implement the following protocol in your code:

    Code Block
    @protocol ADEumCrashReportCallback <NSObject>
      
    - (void)onCrashesReported:(NSArray<ADEumCrashReportSummary *> *)crashReportSummaries;
      
    @end
    Note

    This callback is invoked on your app's UI thread, so any significant work should be done on a separate work thread.

    Each ADEumCrashReportSummary passed in has the following properties:

    Code Block
    @interface ADEumCrashReportSummary : NSObject
     
    /** Uniquely defines the crash, can be used as key to find full crash report. */
    @property (nonatomic, readonly) NSString *crashId;
     
    /** The exception name, may be `nil` if no `NSException` occured. */
    @property (nonatomic, readonly) NSString * ADEUM_NULLABLE exceptionName;
     
    /** The exception reason, may be `nil` if no `NSException` occured. */
    @property (nonatomic, readonly) NSString * ADEUM_NULLABLE exceptionReason;
     
    /** The Mach exception signal name */
    @property (nonatomic, readonly) NSString *signalName;
     
    /** The Mach exception signal code */
    @property (nonatomic, readonly) NSString *signalCode;
     
    @end

    If you are sending the information to another analytics tool, such as Google Analytics, it is best to include all five properties: 

    • exceptionName and exceptionReason are optional and useful for a quick identification of what the crash is. These are only present if the crash cause occurred within an exception reporting runtime, such as Objective-C.
    • signalName and signalCode are useful for quick identification of the crash. These are from the system and are independent of the runtime.
    • For additional information, crashId can be used to look up the crash in the AppDynamics Controller UI.

    For example, to print the crash information to iOS's logger, you could implement an ADEumCrashReportCallback class like this:

    Code Block
    // assumes the containing object has "adopted" the protocol
    - (void)onCrashesReported:(NSArray<ADEumCrashReportSummary *> *)summaries {
        for (ADEumCrashReportSummary *summary in summaries) {
            NSLog(@"Crash ID: %@", summary.crashId);
            NSLog(@"Signal: %@ (%@)", summary.signalName, summary.signalCode);
            NSLog(@"Exception Name:\n%@", summary.exceptionName);
            NSLog(@"Exception Reason:\n%@", summary.exceptionReason);
        }
    }

    You set the object that implements the ADEumCrashReportCallback protocol during agent configuration:

    Code Block
    ADEumAgentConfiguration *config = [ADEumAgentConfiguration new];
    config.crashReportCallback = myCrashReportCallback;

    Your callback is invoked, on the main/UI thread, if a crash from a previous run is detected and collected. See the latest iOS SDK documentation for more information.

    Anchor
    ios-report-errors
    ios-report-errors
    Report Errors and Exceptions

    You can report exceptions using the method reportError from the ADEumInstrumentation class. Reported exceptions will appear in session details.

    The method can have the following two signatures:

    Objective-C Function SignatureDescription
    (void)reportError:(NSError *)error withSeverity (ADEumErrorSeverityLevel)severity;

    Use this signature to report errors, set the severity level of the issue, and send the stack trace.

    Info

    This function signature sends the stack trace by default. If you don't want to send the stack trace, use the function signature below with the additional argument andStackTrace and set its value to NO.

    (void)reportError:(NSError *)error withSeverity:(ADEumErrorSeverityLevel)severity andStackTrace:(BOOL)stacktrace;


    Use this signature to report errors, set the severity level of the issue, and explicitly specify whether the stack trace should be included.

    If you include the stack trace with the reported error by setting stacktrace to YES, you can view the stack trace in the Code Issues Details dialog.

    To report the error without the stack trace, set stacktrace to NO.

    Anchor
    security-levels
    security-levels
    Severity Levels

    You can also set one of the following severity levels for an issue. With the severity level, you can filter errors in the Code Issues Dashboard or Code Issues Analyze.

    • ADEumErrorSeverityLevelInfo
    • ADEumErrorSeverityLevelWarning
    • ADEumErrorSeverityLevelCritical

    Examples of Reporting Errors

    The example below uses the API to report possible exceptions and set the severity level to ADEumErrorSeverityLevelCritical for a failed attempt to perform a file operation.

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
    NSError *err = nil;
    [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"pathToFile" error:&err];
    if (err) {
       [ADEumInstrumentation reportError:err withSeverity:ADEumErrorSeverityLevelCritical, andStackTrace: NO];
    } else {
       ...
    }
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    var err: Error? = nil
    try? FileManager.default.contentsOfDirectory(atPath: "pathToFile")
    if err != nil {
        ADEumInstrumentation.reportError(err, withSeverity: ADEumErrorSeverityLevelCritical, andStackTrace: false)
    } else {
      ...
    }

    You can also create and report custom errors with the following. Note that because reportError is not passed the argument andStackTrace, by default, the stack trace is automatically included with the error.

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
    NSString *domain = @"com.YourCompany.AddUsers.ErrorDomain";
    NSString *desc = NSLocalizedString(@"Unable to add user.", @"");
    NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : desc };
    NSError *error = [NSError errorWithDomain:domain
                                             code:-101
                                         userInfo:userInfo];
    [ADEumInstrumentation reportError:error withSeverity: ADEumErrorSeverityLevelWarning];
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    var domain = "com.YourCompany.AddUsers.ErrorDomain"
    var desc = NSLocalizedString("Unable to add user.", comment: "")
    var userInfo = [NSLocalizedDescriptionKey: desc]
    var error = NSError(domain: domain, code: -101, userInfo: userInfo)
    ADEumInstrumentation.reportError(error, withSeverity: ADEumErrorSeverityLevelWarning)

    Anchor
    anr-detection
    anr-detection
    Configure Application-Not-Responding (ANR) Detection

    By default, the iOS Agent does not detect ANR issues, and when ANR detection is enabled, the ANR issues are reported without stack traces. You must manually enable ANR detection and set a flag to include stack traces through the iOS Agent configuration. For more information about ANR monitoring, see Code Issues. To specify thresholds for ANR issues, see Configure Application Not Responding Thresholds.

    Enable ANR Detection

    You enable the detection of ANR issues by configuring the instrumentation with the anrDetectionEnabled property as shown below.

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
     ADEumAgentConfiguration *adeumAgentConfig = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    // Enable ANR detection
    adeumAgentConfig.anrDetectionEnabled  = YES;
    [ADEumInstrumentation initWithConfiguration:adeumAgentConfig];
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    let config = ADEumAgentConfiguration(appKey: <#EUM_APP_KEY#>);
    // Enable ANR detection
    config.anrDetectionEnabled = true;
    ADEumInstrumentation.initWith(config); 

    Report Stack Traces with ANRs

    In addition to enabling ANR detection, you set the property anrStackTraceEnabled to YES (Objective-C) or true (Swift) to report stack traces with the ANRs. 

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
     ADEumAgentConfiguration *adeumAgentConfig = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    // Enable ANR detection
    adeumAgentConfig.anrDetectionEnabled  = YES;
    // Set the flag to include stack traces with ANRs
    adeumAgentConfig.anrStackTraceEnabled  = YES;
    [ADEumInstrumentation initWithConfiguration:adeumAgentConfig];
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    let config = ADEumAgentConfiguration(appKey: <#EUM_APP_KEY#>)
    // Enable ANR detection
    config.anrDetectionEnabled = true
    // Set the flag to include stack traces with ANRs
    config.anrStackTraceEnabled = true
    ADEumInstrumentation.initWith(config)

     

    Anchor
    disable-crash-reporting
    disable-crash-reporting
    Disable Crash Reporting

    Crash reporting is enabled by default, but you can manually disable crash reporting through the instrumentation configuration. If you are using other crash reporting tools, you might disable crash reporting to minimize conflicts and optimize the crash report results. 

    You can disable crash reporting by configuring the instrumentation with the crashReportingEnabled property as shown in the following code example.

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
    ADEumAgentConfiguration *config = [[ADEumAgentConfiguration alloc] initWithAppKey:appKey];
    config.crashReportingEnabled = No
    [ADEumInstrumentation initWithConfiguration:config];
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    let config = ADEumAgentConfiguration(appKey: <#EUM_APP_KEY#>);
    config.crashReportingEnabled = false;
    ADEumInstrumentation.initWith(config); 

    Anchor
    hybrid-support
    hybrid-support
    Configure Hybrid Application Support

    By default, the iOS Agent instruments iOS WKWebViews, but does not collect and report Ajax calls. See Hybrid Application Support for an overview and an explanation of how it works.

    You can configure the static or runtime configuration to disable hybrid application support or modify its behavior. The sections below show you how to change the defaults for hybrid support through either runtime or static configuration. 

    Anchor
    hybrid-runtime-config
    hybrid-runtime-config
    Runtime Configuration for Hybrid Application Support

    The code example below disables the injection of the JavaScript Agent. By disabling the injection, the WKWebViews in your application will not be instrumented and Ajax calls will not be reported.

    Code Block
    languagecpp
    ADEumAgentConfiguration *adeumAgentConfig = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    // Disable the JavaScript Agent Injection
    adeumAgentConfig.jsAgentEnabled = NO;
    [ADEumInstrumentation initWithConfiguration:adeumAgentConfig];

    The JavaScript Agent injection is enabled by default. To also enable the collection and reporting of Ajax calls:

    Code Block
    languagecpp
    ADEumAgentConfiguration *adeumAgentConfig = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    // Enable the collection and reporting of Ajax calls
    adeumAgentConfig.jsAgentAjaxEnabled  = YES;
    [ADEumInstrumentation initWithConfiguration:adeumAgentConfig];

    Anchor
    hybrid-static-config
    hybrid-static-config
    Static Configuration for Hybrid Application Support

    You should use static configuration for the following reasons:

    • force the instrumentation of WKWebViews and/or Ajax calls (override the runtime configuration)
    • disable hybrid support and override the runtime configuration
    • set the URL to your self-hosted JavaScript Extension file

    The table below describes the supported properties and provides the default value for the info.plist file.

    PropertyDefault ValueDescription

    serverJsAgentEnabled

    true

    If the client receives a false for this flag, then the JavaScript Agent will be disabled. Thus, the WKWebViews and Ajax requests will not be monitored.

    The injection occurs during the creation of a new WKWebView. So, if a WKWebView is created when this flag is set to false, that particular WKWebView won't be instrumented even if the flag is subsequently set to true.

    ForceWebviewInstrumentationfalseWhen set to true, the iOS Agent will inject the JavaScript Agent into the WKWebViews regardless of the runtime configuration.
    ForceAjaxInstrumentationtrueWhen set to true, Ajax operations will always be collected and reported regardless of the runtime configuration.
    ADRUMExtUrlHttp

    http://cdn.appdynamics.com

    The JavaScript Agent consists of two components: the base JavaScript Agent and the JavaScript Agent extension. The base JavaScript Agent is built into the Mobile Agent binary and injected according to the rules above.

    After initialization, the JavaScript Agent fetches the JavaScript Agent extension from the URLs specified by these properties.

    ADRUMExtUrlHttps https://cdn.appdynamics.com/

    Example Configuration

    The example info.plist below forces the instrumentation of WKWebViews (overriding the runtime configuration), but does not force the collection and reporting of Ajax requests. The configuration also sets the URL where the JavaScript Extension file is obtained.

    Code Block
    languagecpp
    <plist>
      <dict>
        ...
        <key>ADEUM_Settings</key>
        <dict>
          <key>ForceWebviewInstrumentation</key>
          <true/>
          <key>ForceAjaxInstrumentation</key>
          <false/>
          <key>ADRUMExtUrlHttp</key>
          <string>http://<your-domain>/adrum.cdn</string>
          <key>ADRUMExtUrlHttps</key>
          <string>https://<your-domain>/adrum.cdn</string>
        </dict>
        ...
     </dict>
    </plist>

    Anchor
    programmatic-sessions
    programmatic-sessions
    Programmatically Control Sessions

    By default, a mobile session ends after a period of user inactivity. For example, when a user opens your application, the session begins and only ends after the user stops using the app for a set period of time. When the user begins to use the application again, a new session begins. 

    Instead of having a period of inactivity to define the duration of a session, however, you can use the following API to programmatically control when sessions begin and end:

    Code Block
    languagecpp
     - (void)startNextSession

    When you call the method startNextSession from the ADEumInstrumentation class, the current session ends and a new session begins. The API enables you to define and frame your sessions so that they align more closely with business goals and expected user flows. For example, you could use the API to define a session that tracks a purchase of a product or registers a new user. 

    Excessive use of this API will cause sessions to be throttled (excessive use is >10 calls per minute per iOS Agent, but is subject to change). When not using the API, sessions will fall back to the default of ending after a period of user inactivity. 

    Example of a Programmatically Controlled Session

    In the example below, the current session ends and a new one begins when the check out is made.

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
    -(void) checkout {
        AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
        NSString *checkoutUrl = [appDelegate.url stringByAppendingString:@"rest/cart/co/"];
        NSURL *url = [NSURL URLWithString:checkoutUrl];
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
        NSURLResponse *response = nil;
        NSError *error = nil;
        
        NSData *body = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
        const char *responseBytes = [body bytes];
        if (responseBytes == nil)
            checkoutResponse = [NSString stringWithUTF8String:"Could not connect to the server"];
        else {
            checkoutResponse = [NSString stringWithUTF8String:responseBytes];
            [ADEumInstrumentation startNextSession];
        }
    }
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    func checkout() {
        let appDelegate = UIApplication.shared.delegate as? AppDelegate
        let checkoutUrl = appDelegate?.url ?? "" + ("rest/cart/co/")
        let url = URL(string: checkoutUrl)
        var request: NSMutableURLRequest? = nil
        if let url = url {
            request = NSMutableURLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60.0)
        }
        var response: URLResponse? = nil
        var error: Error? = nil
        var body: Data? = nil
        if let request = request {
            body = try? NSURLConnection.sendSynchronousRequest(request, returning: &response)
        }
        let responseBytes = Int8(body?.bytes ?? 0)
        if responseBytes == nil {
            checkoutResponse = String(utf8String: "Could not connect to the server")
        } else {
            checkoutResponse = String(utf8String: &responseBytes)
            ADEumInstrumentation.startNextSession()
        }
    }

    Anchor
    session-frames
    session-frames
    Start and End Session Frames

    You can use the SessionFrame API to create session frames that will appear in the session activity. Session frames provide context for what the user is doing during a session. With the API, you can improve the names of user screens and chronicle user flows within a business context. 

    Use Cases

    The following are common use cases for the SessionFrame API:

    • One ViewController performs multiple functions and you want more granular tracking of the individual functions.
    • A user flow spans multiple ViewController or user interactions. For example, you could use the API to create the session frames "Login", "Product Selection", and "Purchase" to chronicle the user flow for purchases.
    • You want to capture dynamic information based on user interactions to name session frames, such as an order ID.

    SessionFrame API

    The table below lists the three methods you can use with session frames. In short, you start a session frame with startSessionFrame and then use the returned ADeumSessionFrame object to rename and end the session frame. 

    Div
    stylewidth: 1050px;
    Tabs Container
    Width1000px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    ClassMethodDescription

    ADEumInstrumentation

    Code Block
    languagecpp
    + (ADEumSessionFrame *)startSessionFrame:(NSString *)name

    Use this to start and name your session frame.

    Naming session frames enable you to easily identify and track the frames in the Sessions Dialog.

    ADEumSessionFrame

    Code Block
    languagecpp
    - (void)updateName:(NSString *)name

    Rename the session frame name.

    You call this method from the ADEumSessionFrame object returned from startSessionFrame.

    ADEumSessionFrame

     

    Code Block
    languagecpp
    - (void)end

    End the session frame.

    You call this method from the ADEumSessionFrame object returned from startSessionFrame.

    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    ClassMethodDescription

    ADEumInstrumentation

    startSessionFrame(_ name: String?) -> ADEumSessionFrameUse this to start and name your session frame. Naming session frames enable you to easily identify and track the frames in the Sessions Dialog.
    ADEumSessionFrame
    updateName(_ name: String?)Rename the session frame name. You call this method from the ADEumSessionFrame object returned from startSessionFrame.
    ADEumSessionFrameend()End the session frame. You call this method from the ADEumSessionFrame object returned from startSessionFrame.

    Session Frame Example

    In the following example, the SessionFrame API is used to track user activity during the checkout process. 

    Tabs Container
    Width1000px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
    #import "ADEumSessionFrame.h"
    ...
    @property (nonatomic, strong) ADEumSessionFrame *checkoutSessionFrame;
    
    - (IBAction)checkoutCartButtonClicked:(id)sender {
        // The user starting to check out starts when the user clicks the checkout button
        // this may be after they have updated quantities of items in their cart, etc.
        checkoutSessionFrame = [ADEumInstrumentation startSessionFrame:@"Checkout"];
    }
    
    - (IBAction)confirmOrderButtonClicked:(id)sender {
        // Once they have confirmed payment info and shipping information, and they
        // are clicking the "Confirm" button to start the backend process of checking out
        // we may know more information about the order itself, such as an Order ID.
        NSString *newSessionName = [NSString stringWithFormat:@"Checkout: Order ID %@",orderId];
        [checkoutSessionFrame updateName:newSessionName];
    }
    
    - (void)processOrderCompleted {
        // Once the order is processed, the user is done "checking out" so we end
        // the session frame
        [checkoutSessionFrame end];
        checkoutSessionFrame = nil;
    }
    
    - (void)checkoutCancelled {
        // If they cancel or go back, you'll want to end the session frame also, or else
        // it will be left open and appear to have never ended.
        [checkoutSessionFrame end];
        checkoutSessionFrame = nil;
    }
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    import ADEumSessionFrame
    ...
    
    var checkoutSessionFrame: ADEumSessionFrame?
    @IBAction func checkoutCartButtonClicked(_ sender: UIButton) {
        // The check out starts when the user clicks the checkout button.
        // This may be after they have updated quantities of items in their cart, etc.
        checkoutSessionFrame = ADEumInstrumentation.startSessionFrame("Checkout")
    }
    
    @IBAction func confirmOrderButtonClicked(_ sender: UIButton) {
        // Once users have confirmed payment info and shipping information, and they
        // are clicking the "Confirm" button to start the backend process of checking out,
        // we may know more information about the order itself, such as an order ID.
        let newSessionName = "Checkout: Order ID \(orderId)"
        checkoutSessionFrame.updateName(newSessionName)
    }
    
    func processOrderCompleted() {
        // Once the order is processed, the user is done "checking out", so we end the session frame.
        checkoutSessionFrame.end()
        checkoutSessionFrame = nil
    }
    
    func checkoutCancelled() {
        // If they cancel or go back, you'll want to end the session frame also, or else it will be
        // left open and appear to have never ended.
        checkoutSessionFrame.end()
        checkoutSessionFrame = nil
    }

    Configure the Agent for Custom App Names

    By default, AppDynamics automatically detects the name of your application. The application name is a string form of the bundle ID. Thus, if the bundle ID is com.example.appdynamics.HelloWorld, the application name will be "com.example.appdynamics.HelloWorld". 

    There may be cases, however, where you deploy essentially the same app binary with different bundle IDs to various regional app stores. To make sure all the data belonging to one app is collected and displayed together, despite varying bundle IDs, you can set a common name by giving the apps a custom name. To do this, set the application name property in the ADEumAgentConfiguration instance that you use to set up ADEumInstrumentation. See the latest iOS SDK documentation for more information.

    Code Block
    @property (nonatomic, strong) NSString *applicationName; 

    Configure the Agent for Ignoring Some HTTP Requests

    In some cases, HTTP requests using NSURL are used for internal purposes in an application and do not represent actual network requests. Metrics created based on these requests are not normally useful in tracking down issues, so preventing data on them from being collected can be useful. To ignore specific NSURL requests, set the excluded URL patterns property in the ADEumAgentConfiguration instance that you use to set up ADEumInstrumentation. Use the simplest regex possible. See the latest iOS SDK documentation for more information.

    Code Block
    languagecpp
    @property (nonatomic, strong) NSSet * excludedUrlPatterns;

    Anchor
    customlib
    customlib
    Use the Agent with a Custom HTTP Library

    The iOS Agent automatically detects network requests when the underlying implementation is handled by either by the NSURLConnection or the NSURLSession classes. This covers the great majority of iOS network requests. In some cases, however, mobile applications use custom HTTP libraries.  

    • To have the iOS Agent detect requests from a custom library, add request tracking code to your application manually, using the ADEumHTTPRequestTracker class.  
    • To set headers to allow correlation with server-side processing, use the ADEumServerCorrelationHeaders class.  
    • To configure the agent to use your custom library to deliver its beacons over HTTP, use the ADEumCollectorChannel protocol and the ADEumAgentConfiguration class.

    Anchor
    tracking
    tracking
    Add Request Tracking

    To add request tracking manually, you tell the agent when the request begins and when it ends. You also set properties to tell the agent the status of the response.

    Start and complete tracking a request

    To begin tracking an HTTP request, call the following method immediately before sending the request.

    Note

     You must initialize the agent using one of the ADEumInstrumentation's initWithKey methods before using this method.

    Code Block
    languagecpp
    @interface ADEumHTTPRequestTracker : NSObject
    ... 
    + (ADEumHTTPRequestTracker *)requestTrackerWithURL:(NSURL *)url;

    Where url is the URL being requested. This parameter must not be nil.

    To complete tracking an HTTP request, immediately after receiving a response or an error, set the appropriate properties on the tracker object and call the following method to report the outcome of the request back to the agent. You should not continue to use this object after calling this method. To track another request, call requestTrackerWithURL again.

    Code Block
    languagecpp
    - (void)reportDone;


    Anchor
    properties
    properties
    Properties to be set

    The following properties should be set on the requestTrackerWithURL object to describe to the agent the results of the call.

    Code Block
    languagecpp
    @property (copy, nonatomic) NSError *error;

    Indicates the failure to receive a response, if this occurred. If the request was successful, this should be nil.

    Code Block
    languagecpp
    @property (copy, nonatomic) NSNumber *statusCode;


    Reports the HTTP status code of the response, if one was received.
    • If a response was received, this should be an integer.

    • If an error occurred and a response was not received, this should be nil.

      Anchor
      headerfields
      headerfields

      Code Block
      languagecpp
      @property (copy, nonatomic) NSDictionary *allHeaderFields;

    Provides a dictionary representing the keys and values from the server’s response header. The format of this dictionary should be identical to the allHTTPHeadersFields property of NSURLRequest. The dictionary elements consist of key/value pairs, where the key is the header key name and the value is the header value.

    If an error occurred and a response was not received, this should be nil.  

    Example:

    Given a request snippet like this:

    Code Block
    languagecpp
    - (NSData *)sendRequest:(NSURL *) url error:(NSError **)error { 
          // implementation omitted 
          NSData *result = nil; 
          if (errorOccurred) { 
              *error = theError; 
          } else { 
              result = responseBody; 
          } 
          return result; 
      }

    Adding the tracker could look something like this:

    Code Block
    languagecpp
    - (NSData *)sendRequest:(NSURL *)url error:(NSError **)error { 
          ADEumHTTPRequestTracker *tracker = [ADEumHTTPRequestTracker requestTrackerWithURL:url]; 
          // implementation omitted 
          NSData *result = nil; 
          if (errorOccurred) { 
              *error = theError; 
              tracker.error = theError; 
          } else { 
              tracker.statusCode = theStatusCode; 
              tracker.allHeaderFields = theResponseHeaders; 
              result = responseBody; 
          } 
          [tracker reportDone]; 
          return result; 
      }

    Anchor
    correlation
    correlation
    Enable Server-Side Correlation

    To enable correlation between your request and server-side processing, add specific headers to outgoing requests that the server-side agent can detect and return the headers obtained from the server-side agent in the response to make them available to the iOS Agent.


    Info

    This is done automatically for standard HTTP libraries.

    Code Block
    languagecpp
    @interface ADEumServerCorrelationHeaders : NSObject 
    + (NSDictionary *)generate; 
    @end

    You must:

    1. Call the generate method and set the generated headers before sending a request to the backend.

    2. Report back the response headers, using the allHeaderFields property shown above.

    Anchor
    configure
    configure
    Configure Agent to Use Custom HTTP Library

    The iOS Agent uses HTTP to deliver its beacons. To have the agent use your custom HTTP library for this purpose, do the following.

    1. Implement a class that conforms to this protocol:

      Code Block
      languagecpp
      /** 
      * Protocol for customizing the connection between the agent SDK and the collector. 
      */ 
      @protocol ADEumCollectorChannel <NSObject> 
       
      /** 
      * Sends a request synchronously and returns the response received, or an error. 
      * 
      * The semantics of this method are exactly equivalent to NSURLConnection's 
      * sendSynchronousRequest:returningResponse:error: method. 
      * 
      * @param request The URL request to load. 
      * @param response Out parameter for the URL response returned by the server. 
      * @param error Out parameter used if an error occurs while processing the request. May be NULL. 
      */ 
      - (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error; 
      @end
    2. Set the collectorChannel property in ADEumAgentConfiguration before initializing ADEumInstrumentation, passing in an instance of your class that implements ADEumCollectorChannel. See the latest iOS SDK documentation for more information.

      Code Block
      languagecpp
      @property (nonatomic, strong) id<ADEumCollectorChannel> collectorChannel;

    Anchor
    ios-capture-user-interaction
    ios-capture-user-interaction
    Capture User Interactions

    You can enable the iOS Agent to track certain UI events triggered by user interactions. Once user interactions have been captured, you can sort sessions by UI event and view UI events in the timeline of the session waterfall. 

    You can capture when users do one or all of the following:

    • press buttons
    • select table cells
    • select text fields
    • select text views
    Info
    titleSecurity and Privacy Concerns

    The interaction capture mode is disabled by default for security and privacy reasons as user interactions may contain sensitive information. Moreover, this potential security and privacy issue may be compounded if you enable both the capturing of UI interactions and screenshots. 

    Enable User Interaction Capture Mode

    To enable user interaction capture mode, you assign the capture mode to the property interactionCaptureMode of the ADEumAgentConfiguration object. The instrumentation code example below configures the iOS Agent to capture all the supported types of user interactions. 

    Code Block
    languagecpp
    ADEumAgentConfiguration *config = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    config.interactionCaptureMode = ADEumInteractionCaptureModeAll;
    [ADEumInstrumentation initWithConfiguration:config];
    

    You can also configure the iOS Agent to only capture one type of user interaction:

    Code Block
    languagecpp
    ADEumAgentConfiguration *config = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    config.interactionCaptureMode = ADEumInteractionCaptureModeButtonPressed;
    [ADEumInstrumentation initWithConfiguration:config];

    Anchor
    ios-screenshots
    ios-screenshots
    Configure and Take Screenshots

    Mobile screenshots are enabled by default. You can configure the Controller UI to automatically take screenshots or use the iOS SDK to manually take a screenshot as shown below:

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
    [ADEumInstrumentation takeScreenshot];
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    ADEumInstrumentation.takeScreenshot()

    Disable Screenshots

    You can disable screenshots from the Controller UI or with the iOS SDK. To disable screenshots with the iOS SDK, set the property screenshotsEnabled of the ADEumAgentConfiguration object to NO for Objective-C and false for Swift as shown below.

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
    ADEumAgentConfiguration *config = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    config.screenshotsEnabled = NO;
    [ADEumInstrumentation initWithConfiguration:config];
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    let config = ADEumAgentConfiguration(appKey: <#EUM_APP_KEY#>);
    config.screenshotsEnabled = false;
    ADEumInstrumentation.initWith(config);

    Block and Unblock Screenshots

    You can also use the iOS SDK to block screenshots from being taken during the execution of a code block. This just temporarily blocks screenshots from being taken until you unblock screenshots. This enables you to stop taking screenshots in situations where users are entering personal data, such as on login and account screens.

    The ADEumInstrumentation class provides the methods blockScreenshots and unblockScreenshots to block and unblock screenshots. If screenshots are disabled through the property screenshotsEnabled of the ADEumAgentConfiguration object or through the Controller UI, these methods have no effect. You can also call screenshotsBlocked to check if screenshots are being blocked.

    The following example demonstrates how you could use the API to block and unblock screenshots for a user login.

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
    #import "ADEumInstrumentation.h"
    ...
    
    - (IBAction)loginUser:(id)sender {
        if(![ADEumInstrumentation screenshotsBlocked]) {
          [ADEumInstrumentation blockScreenshots];
        }
        LoginCredentials creds = [UserLogin getUserCreds];
        if(creds.authorized) {
           [LoginUser redirectToProfile:creds.user]
           [ADEumInstrumentation unblockScreenshots];
        }
    }
    ...
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languagecpp
    import ADEumInstrumentation
    ...
    
    @IBAction func loginUser(_ sender: UIButton) {
        if(!ADEumInstrumentation.screenshotsBlocked()) {
            ADEumInstrumentation.blockScreenshots()
        }
        let creds = UserLogin.getUserCreds()
        if(creds.authorized) {
            LoginUser.redirectToProfile(credits.user)
            ADEumInstrumentation.unblockScreenshots()
        }
    }
    ...

    Anchor
    transform-url-network-requests
    transform-url-network-requests
    Transform URLs for Network Requests

    When your application makes network requests, you may not want to report URLs containing sensitive information to the EUM Server. You can instead transform the network request URL before reporting it or ignore it altogether. 

    To do so:

    1. Implement a network request callback that modifies or ignores specific URLs. 
    2. Register the network request callback in the initialization code.

    Anchor
    implement-nr-callback
    implement-nr-callback
    Implement the Network Request Callback

    The callback that modifies or ignore specific URLs is an implementation of the protocol below. The callback method networkRequestCallback is synchronous, so it is recommended that you return from the function quickly.

    Code Block
    languagecpp
    - (BOOL)networkRequestCallback:(ADEumHTTPRequestTracker *)networkRequest

     Transforming URLs

    The networkRequestCallback method, in general, should follow the steps below to transform URLs:

    1. Identify specific URLs using techniques such as regex or pattern matching.
    2. Modify the url property of the ADEumHTTPRequestTracker object. (Modifying other properties of the ADEumHTTPRequestTracker object will be ignored.)
    3. Assign a valid URL to the url property. 
    4. Return YES (Objective-C) or true (Swift).

    The first step is optional as you could choose to transform the URLs of all network requests. 

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
    - (BOOL)networkRequestCallback:(ADEumHTTPRequestTracker *)networkRequest
    {
        NSString *maskURL = @"http://networkrequest-mask.com";
        NSURL *url = [NSURL URLWithString:maskURL];
        networkRequest.url = url;
        return YES;
    } 
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    func networkRequestCallback(_ networkRequest: ADEumHTTPRequestTracker?) -> Bool {
        let maskURL = "http://networkrequest-mask.com"
        let url = URL(string: maskURL)
        networkRequest?.url = url
        return true
    }

    In general, however, you would want to identify and transform URLs that contain sensitive information as implied in the example below.

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
    - (BOOL)networkRequestCallback:(ADEumHTTPRequestTracker *)networkRequest
    {
        NSString *urlString = networkRequest.url.absoluteString;
        BOOL returnBeacon = YES;
        NSString *maskURL = @"http://customer-account.com";
        if (!([urlString rangeOfString:@"accountInfo"].location == NSNotFound)) {
            networkRequest.url = [NSURL URLWithString:maskURL];
        }
        return returnBeacon;
    }
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    func networkRequestCallback(_ networkRequest: ADEumHTTPRequestTracker?) -> Bool {
        let urlString = networkRequest?.url.absoluteString
        returnBeacon = true
        let maskURL = "http://customer-account.com"
        if !(Int((urlString as NSString?)?.range(of: "accountInfo").location ?? 0) == NSNotFound) {
            networkRequest?.url = URL(string: maskURL)
        }
        return returnBeacon
    }

    Ignoring URLs

    If the networkRequestCallback method returns false, the beacon is dropped. The general process for ignoring beacons is as follows:

    1. Identify specific URLs using techniques such as regex or pattern matching.

    2. Return false.

    You could theoretically ignore all network requests by having the callback networkRequestCallback always return NO (Objective-C) or false (Swift):

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
    - (BOOL)networkRequestCallback:(ADEumHTTPRequestTracker *)networkRequest
    {
        return NO;
    }
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    func networkRequestCallback(_ networkRequest: ADEumHTTPRequestTracker?) -> Bool {
        return false
    }

    In general, though, you would identify network requests that you didn't want to monitor and return NO (Objective-C) or false (Swift) to ignore the network request as implied by this example.

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
    - (BOOL)networkRequestCallback:(ADEumHTTPRequestTracker *)networkRequest
    {
        NSString *urlString = networkRequest.url.absoluteString;
        BOOL returnBeacon = YES;
        if (!([urlString rangeOfString:@"avatar"].location == NSNotFound)) {
            returnBeacon = NO;
        }
        return returnBeacon;
    }
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    func networkRequestCallback(_ networkRequest: ADEumHTTPRequestTracker?) -> Bool {
        let urlString = networkRequest?.url.absoluteString
        var returnBeacon = true
        if !(Int((urlString as NSString?)?.range(of: "avatar").location ?? 0) == NSNotFound) {
            returnBeacon = false
        }
        return returnBeacon
    }

    Anchor
    register-nr-callback
    register-nr-callback
    Register the Callback

    After implementing the callback, you register the object implementing the protocol method in the initialization code as shown below. When the iOS Agent is ready to create a network request beacon, it will first call the callback with an ADEumHTTPRequestTracker object.

    Tabs Container
    Width800px
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
    ADEumAgentConfiguration *config = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    config.networkRequestCallback = self;
    [ADEumInstrumentation initWithConfiguration:config];
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    let config = ADEumAgentConfiguration(appKey: <#EUM_APP_KEY#>)
    config.networkRequestCallback = self
    ADEumInstrumentation.initWith(config)

    Anchor
    ios-enable-set-logging
    ios-enable-set-logging
    Enable Logging and Set Logging Level

    You use the method loggingLevel to enable and set the logging level. You can set logging to one of the following levels:

    • ADEumLoggingLevelOff 

    • ADEumLoggingLevelAll 

    • ADEumLoggingLevelVerbose

    • ADEumLoggingLevelDebug 

    • ADEumLoggingLevelInfo 

    • ADEumLoggingLevelWarn 

    • ADEumLoggingLevelError 

    Info

    Use verbose, all, and debug levels of logging only for troubleshooting and be sure to turn off for production.

    Examples:

    Tabs Container
    directionhorizontal
    Tabs Page
    tabNameObjective-C
    titleObjective-C
    Code Block
    languagecpp
    -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        // appKey should be assigned your EUM app key
        ADEumAgentConfiguration *config = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
        config.loggingLevel = ADEumLoggingLevelAll;
        [ADEumInstrumentation initWithConfiguration:config];
        ...
    }
    Tabs Page
    tabNameSwift 4.2
    titleSwift 4.2
    Code Block
    languageruby
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    {
        // appKey should be assigned your EUM app key
        let config = ADEumAgentConfiguration(appKey: <#EUM_APP_KEY#>)
        config.loggingLevel = .all
        ADEumInstrumentation.initWithConfiguration(config)
        ...
        return true
    }



    Excerpt

    Anchor
    ios-sdk
    ios-sdk
    iOS SDK Documentation

    See the latest iOS SDK documentation or the previous versions listed below:

    Info

    After 4.5.6, the iOS Agent started using a version number different from that of the Controller and the other AppDynamics platform components. See Mobile Agent Version and Deployment Support Matrix for the minimum version of the Controller and the EUM Server required for complete support of all the iOS Agent features.

    Sv translation
    languageja
    Appd tocbox
    Width225px

    On this page

    Table of Contents
    maxLevel2
    excludeiOS SDK.*

    Related pages:

    モバイル iOS SDK を使用して iOS アプリケーションをインストゥルメント化すると、SDK が公開する API を使用して、コントローラ UI に表示されるアプリケーションのデータをカスタマイズすることもできます。

    Info

    エージェントは情報を報告する前にローカルバッファにイベントに関するデータを保存するため、慎重に API を使用することをお勧めします。

    データの追加タイプの収集

    ADEUMInstrumentation クラスで使用可能なメソッドを使用して、6 つの追加タイプのデータを収集できます。

    データのタイプ説明仕様データが表示される場所
    情報ポイントメソッドが呼び出される頻度と実行にかかる時間。
    • データは数値
    • 名前には、英数字
      とスペースを使用
    カスタムタイマーコード内の任意のイベントシーケンスが、
    複数のメソッドにまたがる場合でも、時間を計測。
    • データは数値
    • メトリック名には、英数字
      とスペースを使用
    カスタムメトリック収集する整数ベースのデータ。
    • データは数値
    • メトリック名には、
      英数字とスペースを使用
    ユーザデータ有用と思われる任意の文字列キーと値のペア
    • データは任意のタイプ
    • メトリック名には制限なし
    トピックパス(パンくずリスト)クラッシュのコンテキスト。
    • データは任意のデータ型
    • メトリック名には制限なし
    ユーザの操作ユーザがボタンを押したとき、リストをクリックしたとき、およびテキストを選択したときにキャプチャ。
    • データは任意のデータ型
    • メトリック名には制限なし
    Info

    追加のデータ型を設定した場合、モバイルエージェントはモバイルビーコンでそのデータをパッケージ化します。通常、ビーコンはインストゥルメント化されたアプリケーションが HTTP リクエストを送信したとき、またはクラッシュ後にアプリケーションが再起動されたときに送信されますが、カスタムデータが収集され、これらのイベントのいずれも 5 分以上発生していない場合は、カスタムデータはその時点で送信されます。

    Anchor
    InfPt
    InfPt
    情報ポイント

    情報ポイントを使用すると、独自のコードがどのように実行されているかを追跡できます。次のように beginCallendCall を使用して、メソッドが呼び出される頻度と実行にかかる時間を確認できます。

    Appd tabs container
    Appd tab item
    tabNameObjective-C
    Code Block
    - (void)myMethod
        {
            id tracker = [ADEumInstrumentation beginCall:self selector:_cmd];
    
            // Implementation of method here ...
    
            [ADEumInstrumentation endCall:tracker];
        }
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    func myMethod() {
        let tracker = ADEumInstrumentation.beginCall(self, selector: #function)
        // Implementation of method here ...
        ADEumInstrumentation.endCall(tracker)
    }
    例外がスローされた場合も報告されます。この情報は、コントローラ UI の [Custom Data] ビューに表示されます。  

    Anchor
    CusTim
    CusTim
    カスタムタイマー

    カスタムタイマーでは、startTimerstopTimer を使用して、複数のメソッドにまたがる場合でも、コード内の任意のイベントシーケンスの時間を測定できます。たとえば、ユーザが画面を表示する際にかかった時間を追跡する場合、インストゥルメンテーションは次のようになります。

    Appd tabs container
    Appd tab item
    tabNameObjective-C
    Code Block
    - (void)viewDidAppear:(BOOL)animated {
          [super viewDidAppear:animated];
          [ADEumInstrumentation startTimerWithName:@"View Lifetime"];
      }
    - (void)viewDidDisappear:(BOOL)animated {
          [super viewDidDisappear:animated];
          [ADEumInstrumentation stopTimerWithName:@"View Lifetime"];
      }
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        ADEumInstrumentation.startTimer(withName: "View Lifetime")
    }
    func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        ADEumInstrumentation.stopTimer(withName: "View Lifetime")
    }
     

    この情報は、コントローラ UI の [Custom Data] ビューに表示されます。

    Info

    同じ名前値を使用して startTimerWithName を再度呼び出すと、名前付きタイマーがリセットされます。

    Anchor
    CusMet
    CusMet
    Custom Metrics

    任意の整数ベースのデータをエージェントに渡すことができます。report.MetricWithName コールの最初のパラメータは、メトリックをコントローラ UI に表示する場合の名前です。メトリック名には、英数字とスペースのみを使用します。不正な文字は、ASCII 16 進値に置き換えられます。

    たとえば、「My custom metric」というメトリックを報告する場合は、次のようになります。

    Code Block
    [ADEumInstrumentation reportMetricWithName:@"My custom metric" value:<#VALUE HERE#>];

    この情報は、コントローラ UI の [Custom Data] ビューに表示されます。

    Anchor
    udata
    udata
    ユーザ データ

    有用と思われる任意の文字列キーと値のペアを設定できます。setUserData コールの最初のパラメータは、使用するキーです。これはアプリケーション全体で一意である必要があります。2 番目パラメータは、キーに割り当てる値です。

    例: 

    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    - (void) onUserLoggedIn:(NSString *)userid { 
        [ADEumInstrumentation setUserData:@"User ID" value:userid];
        ...
      }
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    func onUserLogged(in userid: String?) {
        ADEumInstrumentation.setUserData("User ID", value: userid)
    }
    この情報は、[Network Request Analyze] で確認でき、取得可能なクラッシュスナップショットに追加されます。キーと値はそれぞれ 2048 文字に制限されています。 

    また、次のメソッドを使用して、他のデータ型(Long、Boolean、Double、Date)の値を含むユーザデータを設定することもできます。

    Anchor
    iosbread
    iosbread
    トピックパス(パンくずリスト)

    トピックパスを使用すると、ユーザエクスペリエンスのコンテキストでクラッシュの場所を特定できます。問題が発生したときに、トピックパスを設定します。その後のある時点でアプリケーションがクラッシュした場合、トピックパスはクラッシュレポートとともに表示されます。

    トピックパスを残すには、次の 2 つの方法があります。

    Anchor
    nor1
    nor1
    次のメソッドを使用すると、トピックパスがクラッシュレポートのみで報告されます。

    Code Block
    + (void)leaveBreadcrumb:(NSString *)breadcrumb
    Anchor
    mod1
    mod1
    次のメソッドを使用すると、トピックパスが報告される場所を微調整(クラッシュレポートのみ、またはクラッシュレポートとセッションを選択)できます。
    Code Block
    + (void)leaveBreadcrumb:(NSString *)breadcrumb mode:(ADEumBreadcrumbVisibility)mode

    ここで、mode  は次のいずれかです。

    • ADEumBreadcrumbVisibilityCrashesOnly
    • ADEumBreadcrumbVisibilityCrashesAndSessions
    Info

    breadcrumb が 2048 文字を超えている場合は、切り捨てられます。空または nil の場合、トピックパスは記録されません。各クラッシュレポートには、最近の 99 件のトピックパスが表示されます。

     

    Anchor
    crashreport
    crashreport
    クラッシュ レポート コールバックの追加

    モバイル RUM を使用している場合、コードの他の部分(Google Analytics など)がモバイル RUM が収集するクラッシュレポート情報を使用できるようにすることがあります。サマリークラッシュ情報を渡せるようにするには、クラッシュレポートのランタイムコールバックを設定します。iOS エージェントがクラッシュを検出して報告するときにコールバックを取得するには、コードに次のプロトコルを実装する必要があります。

    Code Block
    @protocol ADEumCrashReportCallback <NSObject>
      
    - (void)onCrashesReported:(NSArray<ADEumCrashReportSummary *> *)crashReportSummaries;
      
    @end
    Note

    このコールバックはアプリケーションの UI スレッドで呼び出されるため、重要な作業は別の作業スレッドで実行する必要があります。

    渡される各 ADEumCrashReportSummary には、次のプロパティがあります。

    Code Block
    @interface ADEumCrashReportSummary : NSObject
     
    /** Uniquely defines the crash, can be used as key to find full crash report. */
    @property (nonatomic, readonly) NSString *crashId;
     
    /** The exception name, may be `nil` if no `NSException` occured. */
    @property (nonatomic, readonly) NSString * ADEUM_NULLABLE exceptionName;
     
    /** The exception reason, may be `nil` if no `NSException` occured. */
    @property (nonatomic, readonly) NSString * ADEUM_NULLABLE exceptionReason;
     
    /** The Mach exception signal name */
    @property (nonatomic, readonly) NSString *signalName;
     
    /** The Mach exception signal code */
    @property (nonatomic, readonly) NSString *signalCode;
     
    @end

    Google Analytics などの別の分析ツールに情報を送信する場合は、次の 5 つのプロパティすべてを含めることをお勧めします。

    • exceptionNameexceptionReason はオプションであり、クラッシュの原因をすばやく特定するのに役立ちます。これらは、例外レポートランタイム(Objective-C など)内でクラッシュ原因が発生した場合にのみ表示されます。
    • signalNamesignalCode は、クラッシュをすばやく識別するのに役立ちます。これらはシステムから取得するものであり、ランタイムとは独立しています。
    • その他の情報については、 crashId を使用すると、AppDynamics コントローラ UI でクラッシュを検索できます。

    たとえば、クラッシュ情報を iOS ロガーに出力するには、次のような ADEumCrashReportCallback クラスを実装することもできます。

    Code Block
    // assumes the containing object has "adopted" the protocol
    - (void)onCrashesReported:(NSArray<ADEumCrashReportSummary *> *)summaries {
        for (ADEumCrashReportSummary *summary in summaries) {
            NSLog(@"Crash ID: %@", summary.crashId);
            NSLog(@"Signal: %@ (%@)", summary.signalName, summary.signalCode);
            NSLog(@"Exception Name:\n%@", summary.exceptionName);
            NSLog(@"Exception Reason:\n%@", summary.exceptionReason);
        }
    }

    エージェントの構成時に、ADEumCrashReportCallback プロトコルを実装するオブジェクトを設定します。

    Code Block
    ADEumAgentConfiguration *config = [ADEumAgentConfiguration new];
    config.crashReportCallback = myCrashReportCallback;

    前回の実行からクラッシュの検出と収集が行われた場合、メイン/UI スレッドでコールバックが呼び出されます。詳細については、最新の iOS SDK ドキュメントを参照してください。

    Anchor
    ios-report-errors
    ios-report-errors
    エラーと例外のレポート

    ADEumInstrumentation クラスの reportError メソッドを使用して例外を報告できます。報告された例外は、セッション詳細に表示されます。

    このメソッドには、次の 2 つの署名があります。

    Objective-C 関数の署名説明
    (void)reportError:(NSError *)error withSeverity (ADEumErrorSeverityLevel)severity;

    この署名を使用してエラーを報告し、問題の重大度レベルを設定し、スタックトレースを送信します。

    (void)reportError:(NSError *)error withSeverity:(ADEumErrorSeverityLevel)severity andStackTrace:(BOOL)stacktrace;

     

    この署名を使用してエラーを報告し、問題の重大度レベルを設定し、スタックトレースを含めるかどうかを明示的に指定します。

    stacktraceYES に設定して、報告されるエラーにスタックトレースを含めると、[Code Issues Details] ダイアログにスタックトレースを表示できます。

    スタックトレースなしでエラーを報告するには、stacktraceNO. に設定します。

    Anchor
    security-levels
    security-levels
    重要度レベル

    問題に次の重大度レベルのいずれかを設定することもできます。重大度レベルを使用すると、[Code Issues Dashboard] または [Code Issues Analyze] でエラーをフィルタリングできます。

    • ADEumErrorSeverityLevelInfo
    • ADEumErrorSeverityLevelWarning
    • ADEumErrorSeverityLevelCritical

    エラーレポートの例

    次の例では、API を使用して考えられる例外を報告し、ファイル操作の実行に失敗した場合に重大度を ADEumErrorSeverityLevelCritical に設定します。

    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
    NSError *err = nil;
    [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"pathToFile" error:&err];
    if (err) {
       [ADEumInstrumentation reportError:err withSeverity:ADEumErrorSeverityLevelCritical, andStackTrace: NO];
    } else {
       ...
    }
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    var err: Error? = nil
    try? FileManager.default.contentsOfDirectory(atPath: "pathToFile")
    if err != nil {
        ADEumInstrumentation.reportError(err, withSeverity: ADEumErrorSeverityLevelCritical, andStackTrace: false)
    } else {
      ...
    }
    次のようにカスタムエラーを作成して報告することもできます。reportError では引数 andStackTrace が渡されないため、デフォルトではスタックトレースが自動的にエラーに含まれることに注意してください。
    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
    NSString *domain = @"com.YourCompany.AddUsers.ErrorDomain";
    NSString *desc = NSLocalizedString(@"Unable to add user.", @"");
    NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : desc };
    NSError *error = [NSError errorWithDomain:domain
                                             code:-101
                                         userInfo:userInfo];
    [ADEumInstrumentation reportError:error withSeverity: ADEumErrorSeverityLevelWarning];
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    var domain = "com.YourCompany.AddUsers.ErrorDomain"
    var desc = NSLocalizedString("Unable to add user.", comment: "")
    var userInfo = [NSLocalizedDescriptionKey: desc]
    var error = NSError(domain: domain, code: -101, userInfo: userInfo)
    ADEumInstrumentation.reportError(error, withSeverity: ADEumErrorSeverityLevelWarning)

    Anchor
    anr-detection
    anr-detection
    Application-Not-Responding(ANR)検出の構成

    デフォルトでは、iOS エージェントは ANR 問題を検出しません。また、ANR 検出が有効になっている場合、ANR 問題はスタックトレースなしで報告されます。手動で ANR 検出を有効にし、iOS エージェント構成を使用してスタックトレースを含めるようにフラグを設定する必要があります。ANR モニタリングの詳細については、「Code Issues」を参照してください。ANR 問題のしきい値を指定する場合は、「Configure Application Not Responding Thresholds」を参照してください。

    ANR 検出の有効化

    次に示すように、anrDetectionEnabled プロパティを使用してインストゥルメンテーションを構成することによって、ANR 問題の検出を有効にします

    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
     ADEumAgentConfiguration *adeumAgentConfig = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    // Enable ANR detection
    adeumAgentConfig.anrDetectionEnabled  = YES;
    [ADEumInstrumentation initWithConfiguration:adeumAgentConfig];
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    let config = ADEumAgentConfiguration(appKey: <#EUM_APP_KEY#>);
    // Enable ANR detection
    config.anrDetectionEnabled = true;
    ADEumInstrumentation.initWith(config); 

    ANR を使用したスタックトレースのレポート

    ANR 検出を有効にすることに加えて、プロパティ anrStackTraceEnabledYES(Objective-C)または true(Swift)に設定して、ANR でスタックトレースを報告します。 

    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
     ADEumAgentConfiguration *adeumAgentConfig = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    // Enable ANR detection
    adeumAgentConfig.anrDetectionEnabled  = YES;
    // Set the flag to include stack traces with ANRs
    adeumAgentConfig.anrStackTraceEnabled  = YES;
    [ADEumInstrumentation initWithConfiguration:adeumAgentConfig];
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    let config = ADEumAgentConfiguration(appKey: <#EUM_APP_KEY#>)
    // Enable ANR detection
    config.anrDetectionEnabled = true
    // Set the flag to include stack traces with ANRs
    config.anrStackTraceEnabled = true
    ADEumInstrumentation.initWith(config)
     

    Anchor
    disable-crash-reporting
    disable-crash-reporting
    クラッシュレポートの無効化

    クラッシュレポートはデフォルトで有効になっていますが、インストゥルメンテーション構成を使用して手動でクラッシュレポートを無効にできます。他のクラッシュレポートツールを使用している場合、競合を最小限に抑え、クラッシュレポートの結果を最適化するために、クラッシュレポートを無効にする場合があります。 

    次のコード例に示すように、 crashReportingEnabled プロパティを使用してインストゥルメンテーションを構成することにより、クラッシュレポートを無効にできます。

    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
    ADEumAgentConfiguration *config = [[ADEumAgentConfiguration alloc] initWithAppKey:appKey];
    config.crashReportingEnabled = No
    [ADEumInstrumentation initWithConfiguration:config];
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    let config = ADEumAgentConfiguration(appKey: <#EUM_APP_KEY#>);
    config.crashReportingEnabled = false;
    ADEumInstrumentation.initWith(config); 

    Anchor
    hybrid-support
    hybrid-support
    ハイブリッド アプリケーション サポートの構成

    デフォルトでは、iOS エージェントは iOS WKWebView をインストゥルメント化しますが、Ajax コールを収集して報告することはありません。この機能の概要と説明については、「Hybrid Application Support」を参照してください。

    ハイブリッド アプリケーション サポートを無効にしたり、動作を変更したりするには、静的またはランタイム構成を設定します。次のセクションでは、ランタイム構成または静的構成のいずれかを使用して、ハイブリッドサポートのデフォルト設定を変更する方法を示します。 

    Anchor
    hybrid-runtime-config
    hybrid-runtime-config
    ハイブリッド アプリケーション サポートのランタイム構成

    次のコード例では、JavaScript エージェントのインジェクションを無効にしています。インジェクションを無効にすると、アプリケーション内の WKWebView はインストゥルメント化されず、Ajax コールは報告されません。

    Code Block
    languagecpp
    ADEumAgentConfiguration *adeumAgentConfig = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    // Disable the JavaScript Agent Injection
    adeumAgentConfig.jsAgentEnabled = NO;
    [ADEumInstrumentation initWithConfiguration:adeumAgentConfig];

    JavaScript エージェントのインジェクションはデフォルトで有効になっています。Ajax コールの収集とレポートも有効にするには、次のようにします。

    Code Block
    languagecpp
    ADEumAgentConfiguration *adeumAgentConfig = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    // Enable the collection and reporting of Ajax calls
    adeumAgentConfig.jsAgentAjaxEnabled  = YES;
    [ADEumInstrumentation initWithConfiguration:adeumAgentConfig];

    Anchor
    hybrid-static-config
    hybrid-static-config
    ハイブリッド アプリケーション サポートの静的構成

    次の場合には、静的構成を使用する必要があります。

    • 強制的に WKWebView や Ajax コールをインストゥルメント化する(ランタイム構成をオーバーライドする)
    • ハイブリッドサポートを無効にし、ランタイム構成をオーバーライドする
    • URL を自己ホストされた JavaScript 拡張ファイルに設定する

    次の表は、info.plist ファイルでサポートされているプロパティとデフォルト値です。

    プロパティデフォルト値説明

    serverJsAgentEnabled

    true

    クライアントがこのフラグに false を受け取ると、JavaScript エージェントは無効になります。したがって、WKWebView と Ajax リクエストはモニタされません。

    インジェクションは、新しい WKWebView の作成時に発生します。このため、このフラグが false に設定されているときに WKWebView が作成された場合、その特定の WKWebView は、 その後フラグが true に設定されてもインストゥルメント化されません。

    ForceWebviewInstrumentationfalsetrue に設定すると、iOS エージェントはランタイム構成に関係なく、JavaScript エージェントを WKWebView に挿入します。
    ForceAjaxInstrumentationtruetrue に設定すると、ランタイム構成に関係なく、Ajax オペレーションは常に収集および報告されます。
    ADRUMExtUrlHttp

    http://cdn.appdynamics.com

    JavaScript エージェントは、基本 JavaScript エージェントと JavaScript エージェントの拡張という 2 つのコンポーネントで構成されています。基本 JavaScript エージェントは、モバイルエージェントのバイナリに組み込まれ、上記のルールに従って挿入されます。

    初期化後、JavaScript エージェントは、これらのプロパティによって指定された URL から JavaScript エージェント拡張を取得します。

    ADRUMExtUrlHttpshttps://cdn.appdynamics.com/

    構成例

    次の info.plist の例では、強制的に WKWebView をインストゥルメント化(ランタイム構成をオーバーライド)しますが、Ajax リクエストの収集とレポートは強制されません。この構成では、JavaScript 拡張ファイルが取得される URL も設定されます。

    Code Block
    languagecpp
    <plist>
      <dict>
        ...
        <key>ADEUM_Settings</key>
        <dict>
          <key>ForceWebviewInstrumentation</key>
          <true/>
          <key>ForceAjaxInstrumentation</key>
          <false/>
          <key>ADRUMExtUrlHttp</key>
          <string>http://<your-domain>/adrum.cdn</string>
          <key>ADRUMExtUrlHttps</key>
          <string>https://<your-domain>/adrum.cdn</string>
        </dict>
        ...
     </dict>
    </plist>

    Anchor
    programmatic-sessions
    programmatic-sessions
    プログラムによるセッションの制御

    デフォルトでは、一定期間ユーザが非アクティブになるとモバイルセッションが終了します。たとえば、ユーザがアプリケーションを開くと、セッションは開始され、ユーザが設定した期間にアプリケーションを使用しなくなった後にのみ終了します。ユーザがアプリケーションの使用を再び開始すると、新しいセッションが開始されます。 

    ただし、セッションの期間を定義するのに非アクティブな期間を設定する代わりに、次の API を使用して、セッションの開始と終了をプログラムで制御できます。

    Code Block
    languagecpp
     - (void)startNextSession

    ADEumInstrumentation クラスの startNextSession メソッドを呼び出すと、現在のセッションが終了し、新しいセッションが開始されます。API を使用すると、セッションを定義してフレーム化できます。これにより、ビジネス目標と適切なユーザフローにより厳密に合わせることができます。たとえば、API を使用して、製品の購入を追跡したり、新しいユーザを登録したりするセッションを定義できます。 

    この API を過剰に使用すると、セッションが調整されます(過剰使用は iOS エージェントごとに 1 分あたり 10 コールを超えた場合になりますが、変更される可能性があります)。API を使用しない場合、セッションはデフォルトである、ユーザが非アクティブになって一定期間後に終了する設定に戻ります。 

    プログラムによって制御されるセッションの例

    次の例では、現在のセッションが終了し、チェックアウトが行われると新しいセッションが開始されます。

    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
    -(void) checkout {
        AppDelegate *appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
        NSString *checkoutUrl = [appDelegate.url stringByAppendingString:@"rest/cart/co/"];
        NSURL *url = [NSURL URLWithString:checkoutUrl];
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
        NSURLResponse *response = nil;
        NSError *error = nil;
        
        NSData *body = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
        const char *responseBytes = [body bytes];
        if (responseBytes == nil)
            checkoutResponse = [NSString stringWithUTF8String:"Could not connect to the server"];
        else {
            checkoutResponse = [NSString stringWithUTF8String:responseBytes];
            [ADEumInstrumentation startNextSession];
        }
    }
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    func checkout() {
        let appDelegate = UIApplication.shared.delegate as? AppDelegate
        let checkoutUrl = appDelegate?.url ?? "" + ("rest/cart/co/")
        let url = URL(string: checkoutUrl)
        var request: NSMutableURLRequest? = nil
        if let url = url {
            request = NSMutableURLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60.0)
        }
        var response: URLResponse? = nil
        var error: Error? = nil
        var body: Data? = nil
        if let request = request {
            body = try? NSURLConnection.sendSynchronousRequest(request, returning: &response)
        }
        let responseBytes = Int8(body?.bytes ?? 0)
        if responseBytes == nil {
            checkoutResponse = String(utf8String: "Could not connect to the server")
        } else {
            checkoutResponse = String(utf8String: &responseBytes)
            ADEumInstrumentation.startNextSession()
        }
    }

    Anchor
    session-frames
    session-frames
    セッションフレームの開始と終了

    SessionFrame API を使用して、セッションアクティビティに表示されるセッションフレームを作成できます。セッションフレームは、セッション中にユーザが実行する内容にコンテキストを指定します。この API を使用すると、ユーザ画面の命名方法が向上し、ビジネスコンテキスト内のユーザフローを記録できます。 

    使用例

    次に、SessionFrame API の一般的な使用例を示します。

    • 1 つの ViewController では複数の関数が実行されていて、個々の関数をより詳細に追跡する必要があります。
    • ユーザフローは、複数の ViewController またはユーザの操作におよびます。たとえば、API を使用してセッションフレーム「Login」、「Product Selection」、および「Purchase」を作成して、購入のためのユーザフローを記録できます。
    • ユーザの操作に基づいて動的情報をキャプチャし、オーダー ID などのセッションフレームに名前を付けることができます。

    SessionFrame API

    次の表に、セッションフレームで使用できる 3 つのメソッドを示します。つまり、startSessionFrame を使用してセッションフレームを開始してから、返された ADeumSessionFrame オブジェクトを使用してセッションフレームの名前を変更し、終了します。 

    Div
    stylewidth: 1050px;

    Appd tabs container
    Width1000px
    Appd tab item
    tabNameObjective-C
    クラスメソッド[説明(Description)]

    ADEumInstrumentation

    Code Block
    languagecpp
    + (ADEumSessionFrame *)startSessionFrame:(NSString *)name

    セッションフレームを開始して名前を付けるには、これを使用します。

    セッションフレームに名前を付けると、次のダイアログでフレームを簡単に識別して追跡できます。Sessions Dialog.

    ADEumSessionFrame

    Code Block
    languagecpp
    - (void)updateName:(NSString *)name

    セッションフレームの名前を変更します。

    startSessionFrame から返された ADEumSessionFrame オブジェクトからこのメソッドを呼び出すことができます。

    ADEumSessionFrame

     

    Code Block
    languagecpp
    - (void)end

    セッションフレームを終了します。

    startSessionFrame から返された ADEumSessionFrame オブジェクトからこのメソッドを呼び出すことができます。

    Appd tab item
    tabNameSwift 4.2
    クラスメソッド[説明(Description)]

    ADEumInstrumentation

    startSessionFrame(_ name: String?) -> ADEumSessionFrameセッションフレームを開始して名前を付けるには、これを使用します。セッションフレームに名前を付けると、次のダイアログでフレームを簡単に識別して追跡できます。Sessions Dialog.
    ADEumSessionFrame
    updateName(_ name: String?)セッションフレームの名前を変更します。startSessionFrame から返された ADEumSessionFrame オブジェクトからこのメソッドを呼び出すことができます。
    ADEumSessionFrameend()セッションフレームを終了します。startSessionFrame から返された ADEumSessionFrame オブジェクトからこのメソッドを呼び出すことができます。

    セッションフレームの例

    次の例では、 SessionFrameチェックアウトプロセス中にユーザアクティビティを追跡するために API が使用されます。 

    Appd tabs container
    Width1000px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
    #import "ADEumSessionFrame.h"
    ...
    @property (nonatomic, strong) ADEumSessionFrame *checkoutSessionFrame;
    
    - (IBAction)checkoutCartButtonClicked:(id)sender {
        // The user starting to check out starts when the user clicks the checkout button
        // this may be after they have updated quantities of items in their cart, etc.
        checkoutSessionFrame = [ADEumInstrumentation startSessionFrame:@"Checkout"];
    }
    
    - (IBAction)confirmOrderButtonClicked:(id)sender {
        // Once they have confirmed payment info and shipping information, and they
        // are clicking the "Confirm" button to start the backend process of checking out
        // we may know more information about the order itself, such as an Order ID.
        NSString *newSessionName = [NSString stringWithFormat:@"Checkout: Order ID %@",orderId];
        [checkoutSessionFrame updateName:newSessionName];
    }
    
    - (void)processOrderCompleted {
        // Once the order is processed, the user is done "checking out" so we end
        // the session frame
        [checkoutSessionFrame end];
        checkoutSessionFrame = nil;
    }
    
    - (void)checkoutCancelled {
        // If they cancel or go back, you'll want to end the session frame also, or else
        // it will be left open and appear to have never ended.
        [checkoutSessionFrame end];
        checkoutSessionFrame = nil;
    }
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    import ADEumSessionFrame
    ...
    
    var checkoutSessionFrame: ADEumSessionFrame?
    @IBAction func checkoutCartButtonClicked(_ sender: UIButton) {
        // The check out starts when the user clicks the checkout button.
        // This may be after they have updated quantities of items in their cart, etc.
        checkoutSessionFrame = ADEumInstrumentation.startSessionFrame("Checkout")
    }
    
    @IBAction func confirmOrderButtonClicked(_ sender: UIButton) {
        // Once users have confirmed payment info and shipping information, and they
        // are clicking the "Confirm" button to start the backend process of checking out,
        // we may know more information about the order itself, such as an order ID.
        let newSessionName = "Checkout: Order ID \(orderId)"
        checkoutSessionFrame.updateName(newSessionName)
    }
    
    func processOrderCompleted() {
        // Once the order is processed, the user is done "checking out", so we end the session frame.
        checkoutSessionFrame.end()
        checkoutSessionFrame = nil
    }
    
    func checkoutCancelled() {
        // If they cancel or go back, you'll want to end the session frame also, or else it will be
        // left open and appear to have never ended.
        checkoutSessionFrame.end()
        checkoutSessionFrame = nil
    }

    カスタムアプリケーション名のエージェントの構成

    デフォルトでは、AppDynamics はアプリケーションの名前を自動的に検出します。アプリケーション名は、バンドル ID の文字列形式です。したがって、バンドル ID が com.example.appdynamics.HelloWorld の場合、アプリケーション名は「com.example.appdynamics.HelloWorld」となります。 

    ただし、原則としてさまざまな地域のアプリケーションストアに異なるバンドル ID を付けたアプリケーションバイナリを展開することがあります。バンドル ID が異なる場合でも、1 つのアプリケーションに属するすべてのデータがまとめて収集され表示されるようにするには、アプリケーションにカスタム名を指定して共通名を設定します。これを行うには、ADEumInstrumentation の設定に使用する ADEumAgentConfiguration インスタンスでアプリケーション名プロパティを設定します。詳細については、最新の iOS SDK ドキュメントを参照してください。

    Code Block
    @property (nonatomic, strong) NSString *applicationName; 

    一部の HTTP リクエストを無視するためのエージェントの構成

    NSURL を使用した HTTP リクエストは、アプリケーションの内部で使用され、実際のネットワークリクエストを表すものではない場合があります。これらのリクエストに基づいて作成されたメトリックは、一般的に問題の追跡には役立たないため、そのデータが収集されないようにする場合があります。特定の NSURL リクエストを無視するには、ADEumInstrumentation の設定に使用する ADEumAgentConfiguration インスタンスに除外 URL パターンプロパティを設定します。できるだけ簡潔な正規表現を使用します。詳細については、最新の iOS SDK ドキュメントを参照してください。

    Code Block
    languagecpp
    @property (nonatomic, strong) NSSet * excludedUrlPatterns;

    Anchor
    customlib
    customlib
    カスタム HTTP ライブラリでのエージェントの使用

    iOS エージェントは、 NSURLConnection または NSURLSession クラスのいずれかによって基盤となる実装が処理されたときに、自動的にネットワークリクエストを検出します。これにより、ほとんどの iOS ネットワークリクエストが対象になります。ただし、モバイルアプリケーションでは、カスタム HTTP ライブラリが使用される場合があります。  

    Anchor
    トラッキング
    トラッキング
    リクエストトラッキングの追加

    リクエストトラッキングを手動で追加するには、リクエストの開始と終了のタイミングをエージェントに通知します。また、応答のステータスをエージェントに通知するようにプロパティを設定します。

    リクエストのトラッキングを開始して完了する

    HTTP リクエストのトラッキングを開始するには、リクエストを送信する直前に次のメソッドを呼び出します。

    Note

    このメソッドを使用する前に、 ADEumInstrumentationinitWithKey メソッドのいずれかを使用してエージェントを初期化する必要があります。

    Code Block
    languagecpp
    @interface ADEumHTTPRequestTracker : NSObject
    ... 
    + (ADEumHTTPRequestTracker *)requestTrackerWithURL:(NSURL *)url;

    ここで、url は要求されている URL です。このパラメータに nil は使用できません。

    HTTP リクエストのトラッキングを完了するには、応答またはエラーを受信した直後に、トラッカーオブジェクトに適切な properties を設定し、次のメソッドを呼び出してリクエストの結果をエージェントに返します。このメソッドを呼び出した後は、このオブジェクトを使用し続けることはできません。別のリクエストを追跡するには、requestTrackerWithURL を再度呼び出します。

    Code Block
    languagecpp
    - (void)reportDone;


    Anchor
    プロパティ
    プロパティ
    設定するプロパティ

    エージェントにコールの結果を返すには、requestTrackerWithURL オブジェクトに次のプロパティを設定する必要があります。

    Code Block
    languagecpp
    @property (copy, nonatomic) NSError *error;

    応答の受信に失敗した場合を示します。リクエストが成功した場合は、nil である必要があります。

    Code Block
    languagecpp
    @property (copy, nonatomic) NSNumber *statusCode;

     

    応答の HTTP ステータスコード(受信した場合)を示します。
    • 応答を受信した場合は、整数である必要があります。

    • エラーが発生し、応答が受信されなかった場合、これは nil にする必要があります。

      Anchor
      headerfields
      headerfields

      Code Block
      languagecpp
      @property (copy, nonatomic) NSDictionary *allHeaderFields;

    サーバの応答ヘッダーのキーと値を表すディクショナリを指定します。このディクショナリの形式は、NSURLRequestallHTTPHeadersFields プロパティと同じである必要があります。ディクショナリエレメントは、キーと値のペアで構成されます。キーはヘッダーキー名で、値はヘッダー値です。

    エラーが発生し、応答が受信されなかった場合、これは nil にする必要があります。  

    例:

    次のようなリクエストスニペットがあるとします。

    Code Block
    languagecpp
    - (NSData *)sendRequest:(NSURL *) url error:(NSError **)error { 
          // implementation omitted 
          NSData *result = nil; 
          if (errorOccurred) { 
              *error = theError; 
          } else { 
              result = responseBody; 
          } 
          return result; 
      }

    トラッカーを追加すると、次のようになります。

    Code Block
    languagecpp
    - (NSData *)sendRequest:(NSURL *)url error:(NSError **)error { 
          ADEumHTTPRequestTracker *tracker = [ADEumHTTPRequestTracker requestTrackerWithURL:url]; 
          // implementation omitted 
          NSData *result = nil; 
          if (errorOccurred) { 
              *error = theError; 
              tracker.error = theError; 
          } else { 
              tracker.statusCode = theStatusCode; 
              tracker.allHeaderFields = theResponseHeaders; 
              result = responseBody; 
          } 
          [tracker reportDone]; 
          return result; 
      }

    Anchor
    相関
    相関
    Enable Server-Side Correlation

    リクエストとサーバ側の処理の相関を有効にするには、サーバ側エージェントが検出できる発信リクエストに特定のヘッダーを追加し、応答でサーバ側エージェントから取得したヘッダーを返して、iOS エージェントが使用できるようにします。

     

    Info

    これは、標準 HTTP ライブラリに対して自動的に実行されます。

    Code Block
    languagecpp
    @interface ADEumServerCorrelationHeaders : NSObject 
    + (NSDictionary *)generate; 
    @end

    次の作業が必要です。

    1. バックエンドにリクエストを送信する前に、generateメソッドを呼び出し、生成されたヘッダーを設定します。

    2. 上記の allHeaderFields プロパティを使用して、応答ヘッダーを返します。

    Anchor
    設定
    設定
    Configure Agent to Use Custom HTTP Library

    iOS エージェントは、ビーコンを送信するために HTTP を使用します。この目的で、エージェントがカスタム HTTP ライブラリを使用する構成を行うには、次の手順を実行します。

    1. このプロトコルに準拠したクラスを実装します。

      Code Block
      languagecpp
      /** 
      * Protocol for customizing the connection between the agent SDK and the collector. 
      */ 
      @protocol ADEumCollectorChannel <NSObject> 
       
      /** 
      * Sends a request synchronously and returns the response received, or an error. 
      * 
      * The semantics of this method are exactly equivalent to NSURLConnection's 
      * sendSynchronousRequest:returningResponse:error: method. 
      * 
      * @param request The URL request to load. 
      * @param response Out parameter for the URL response returned by the server. 
      * @param error Out parameter used if an error occurs while processing the request. May be NULL. 
      */ 
      - (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error; 
      @end
    2. ADEumInstrumentation を初期化する前に ADEumAgentConfigurationcollectorChannel プロパティを設定します。これは ADEumCollectorChannel を実装するクラスのインスタンスを渡します。詳細については、最新の iOS SDK ドキュメントを参照してください。

      Code Block
      languagecpp
      @property (nonatomic, strong) id<ADEumCollectorChannel> collectorChannel;

    Anchor
    ios-capture-user-interaction
    ios-capture-user-interaction
    ユーザインタラクションのキャプチャ

    iOS エージェントが、ユーザインタラクションによってトリガーされた特定の UI イベントを追跡するように設定できます。ユーザインタラクションがキャプチャされると、UI イベントでセッションをソートし、セッション ウォーターフォールのタイムラインで UI イベントを表示できます。 

    ユーザが次のいずれかまたはすべてを実行するときにキャプチャできます。

    • ボタンのクリック
    • テーブルセルの選択
    • テキストフィールドの選択
    • テキストビューの選択
    Info
    titleセキュリティおよびプライバシー上の懸念点

    インタラクション キャプチャ モードは、セキュリティとプライバシー上の理由でデフォルトでは無効になっています。これは、ユーザインタラクションに機密情報が含まれている可能性があるためです。さらに、UI インタラクションとスクリーンショットのキャプチャの両方を有効にすると、このような潜在的なセキュリティとプライバシー上の問題が複合化する場合があります。 

    ユーザ インタラクション キャプチャ モードの有効化

    ユーザ インタラクション キャプチャ モードを有効にするには、ADEumAgentConfiguration オブジェクトの interactionCaptureMode プロパティにキャプチャモードを割り当てます。次のインストゥルメンテーション コードの例では、サポートされているすべてのタイプのユーザインタラクションをキャプチャするように iOS エージェントを構成します。 

    Code Block
    languagecpp
    ADEumAgentConfiguration *config = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    config.interactionCaptureMode = ADEumInteractionCaptureModeAll;
    [ADEumInstrumentation initWithConfiguration:config];
    

    また、1 つのタイプのユーザインタラクションのみをキャプチャするように iOS エージェントを構成することもできます。

    Code Block
    languagecpp
    ADEumAgentConfiguration *config = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    config.interactionCaptureMode = ADEumInteractionCaptureModeButtonPressed;
    [ADEumInstrumentation initWithConfiguration:config];

    Anchor
    ios-screenshots
    ios-screenshots
    スクリーンショットの設定および作成

    モバイルスクリーンショットはデフォルトで有効になっています。スクリーンショットを自動的に取得するようにコントローラ UI を構成するか、次に示すように、iOS SDK を使用して手動でスクリーンショットを取得できます。

    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
    [ADEumInstrumentation takeScreenshot];
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    ADEumInstrumentation.takeScreenshot()

    スクリーンショットの無効化

    スクリーンショットは、コントローラ UI または iOS SDK を使用して無効にできます。iOS SDK を使用してスクリーンショットを無効にするには、次に示すように ADEumAgentConfiguration オブジェクトのプロパティ screenshotsEnabledNO(Objective-C の場合)または false(Swift の場合)に設定します。

    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
    ADEumAgentConfiguration *config = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    config.screenshotsEnabled = NO;
    [ADEumInstrumentation initWithConfiguration:config];
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    let config = ADEumAgentConfiguration(appKey: <#EUM_APP_KEY#>);
    config.screenshotsEnabled = false;
    ADEumInstrumentation.initWith(config);

    スクリーンショットのブロックとブロック解除

    iOS SDK を使用して、コードブロックの実行中にスクリーンショットが実行されないようにすることもできます。スクリーンショットのブロックを解除するまで、スクリーンショットの取得が一時的にブロックされます。これにより、ユーザがログインやアカウント画面などで個人データを入力する状況でのスクリーンショットの取得を停止できます。

    ADEumInstrumentation クラスでは、スクリーンショットをブロックおよびブロック解除するためのメソッド、blockScreenshotsunblockScreenshots が使用できます。スクリーンショットが ADEumAgentConfiguration オブジェクトの screenshotsEnabled プロパティまたはコントローラ UI によって無効になっている場合、これらのメソッドは無効になります。スクリーンショットがブロックされているかどうかを確認するために screenshotsBlocked を呼び出すこともできます。

    次の例は、API を使用して、ユーザログインのスクリーンショットをブロックおよびブロック解除する方法を示しています。

    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
    #import "ADEumInstrumentation.h"
    ...
    
    - (IBAction)loginUser:(id)sender {
        if(![ADEumInstrumentation screenshotsBlocked]) {
          [ADEumInstrumentation blockScreenshots];
        }
        LoginCredentials creds = [UserLogin getUserCreds];
        if(creds.authorized) {
           [LoginUser redirectToProfile:creds.user]
           [ADEumInstrumentation unblockScreenshots];
        }
    }
    ...
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languagecpp
    import ADEumInstrumentation
    ...
    
    @IBAction func loginUser(_ sender: UIButton) {
        if(!ADEumInstrumentation.screenshotsBlocked()) {
            ADEumInstrumentation.blockScreenshots()
        }
        let creds = UserLogin.getUserCreds()
        if(creds.authorized) {
            LoginUser.redirectToProfile(credits.user)
            ADEumInstrumentation.unblockScreenshots()
        }
    }
    ...

    Anchor
    transform-url-network-requests
    transform-url-network-requests
    ネットワークリクエストの URL の変換

    アプリケーションがネットワークリクエストを行う場合、機密情報が含まれている URL を EUM サーバに報告したくない場合があります。その場合は、ネットワークリクエスト URL を報告する前に変換するか、すべて無視します。 

    インポートを行うには以下を実行します。

    1. 特定の URL を変更または無視するネットワーク リクエスト コールバックを実装します。 
    2. 初期化コードにネットワーク リクエスト コールバックを登録します。

    Anchor
    implement-nr-callback
    implement-nr-callback
    ネットワーク リクエスト コールバックの実装

    特定の URL を変更または無視するコールバックでは、次のようにプロトコルを実装します。コールバックメソッド networkRequestCallback は同期的に実行されるので、関数からすぐに戻ることをお勧めします。

    Code Block
    languagecpp
    - (BOOL)networkRequestCallback:(ADEumHTTPRequestTracker *)networkRequest

    URL の変換

    通常 、networkRequestCallback メソッドは次の手順に従って URL を変換する必要があります。

    1. 正規表現やパターンマッチングなどの手法を使用して、特定の URL を識別します。
    2. ADEumHTTPRequestTracker オブジェクトの url プロパティを変更します。ADEumHTTPRequestTracker オブジェクトのその他のプロパティの変更は無視されます。)
    3. url プロパティに有効な URL を割り当てます。 
    4. YES(Objective-C)または true(Swift)を返します。

    すべてのネットワークリクエストの URL を変換することもできるので、最初の手順はオプションです。 

    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
    - (BOOL)networkRequestCallback:(ADEumHTTPRequestTracker *)networkRequest
    {
        NSString *maskURL = @"http://networkrequest-mask.com";
        NSURL *url = [NSURL URLWithString:maskURL];
        networkRequest.url = url;
        return YES;
    } 
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    func networkRequestCallback(_ networkRequest: ADEumHTTPRequestTracker?) -&gt; Bool {
        let maskURL = "http://networkrequest-mask.com"
        let url = URL(string: maskURL)
        networkRequest?.url = url
        return true
    }
    ただし、一般的には次の例に示すように、機密情報が含まれている URL を特定して変換する必要があります。
    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
    - (BOOL)networkRequestCallback:(ADEumHTTPRequestTracker *)networkRequest
    {
        NSString *urlString = networkRequest.url.absoluteString;
        BOOL returnBeacon = YES;
        NSString *maskURL = @"http://customer-account.com";
        if (!([urlString rangeOfString:@"accountInfo"].location == NSNotFound)) {
            networkRequest.url = [NSURL URLWithString:maskURL];
        }
        return returnBeacon;
    }
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    func networkRequestCallback(_ networkRequest: ADEumHTTPRequestTracker?) -&gt; Bool {
        let urlString = networkRequest?.url.absoluteString
        returnBeacon = true
        let maskURL = "http://customer-account.com"
        if !(Int((urlString as NSString?)?.range(of: "accountInfo").location ?? 0) == NSNotFound) {
            networkRequest?.url = URL(string: maskURL)
        }
        return returnBeacon
    }

    URL の無視

    networkRequestCallback メソッドが false を返した場合、ビーコンはドロップされます。ビーコンを無視する一般的なプロセスは次のとおりです。

    1. 正規表現やパターンマッチングなどの手法を使用して、特定の URL を識別します。

    2. false を返します。

    コールバック networkRequestCallback が常に NO(Objective-C)または false(Swift)を返すようにすれば、理論的にはすべてのネットワークリクエストを無視できます。

    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
    - (BOOL)networkRequestCallback:(ADEumHTTPRequestTracker *)networkRequest
    {
        return NO;
    }
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    func networkRequestCallback(_ networkRequest: ADEumHTTPRequestTracker?) -&gt; Bool {
        return false
    }
    ただし、一般的には次の例に示すように、モニタしないネットワークリクエストを識別し、NO(Objective-C)または false(Swift)を返して、ネットワークリクエストを無視します。
    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
    - (BOOL)networkRequestCallback:(ADEumHTTPRequestTracker *)networkRequest
    {
        NSString *urlString = networkRequest.url.absoluteString;
        BOOL returnBeacon = YES;
        if (!([urlString rangeOfString:@"avatar"].location == NSNotFound)) {
            returnBeacon = NO;
        }
        return returnBeacon;
    }
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    func networkRequestCallback(_ networkRequest: ADEumHTTPRequestTracker?) -&gt; Bool {
        let urlString = networkRequest?.url.absoluteString
        var returnBeacon = true
        if !(Int((urlString as NSString?)?.range(of: "avatar").location ?? 0) == NSNotFound) {
            returnBeacon = false
        }
        return returnBeacon
    }

    Anchor
    register-nr-callback
    register-nr-callback
    コールバックの登録

    コールバックを実装した後、次に示すようにプロトコルメソッドを実装するオブジェクトを初期化コードに登録します。iOS エージェントがネットワーク リクエスト ビーコンを作成する準備ができたら、最初に ADEumHTTPRequestTracker オブジェクトを使用してコールバックを呼び出します。

    Appd tabs container
    Width800px
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
    ADEumAgentConfiguration *config = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
    config.networkRequestCallback = self;
    [ADEumInstrumentation initWithConfiguration:config];
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    let config = ADEumAgentConfiguration(appKey: <#EUM_APP_KEY#>)
    config.networkRequestCallback = self
    ADEumInstrumentation.initWith(config)

    Anchor
    ios-enable-set-logging
    ios-enable-set-logging
    ロギングの有効化とロギングレベルの設定

    ロギングレベルを有効にして設定するには、メソッド loggingLevel を使用します。ロギングは、次のいずれかのレベルに設定できます。

    • ADEumLoggingLevelOff 

    • ADEumLoggingLevelAll 

    • ADEumLoggingLevelVerbose

    • ADEumLoggingLevelDebug 

    • ADEumLoggingLevelInfo 

    • ADEumLoggingLevelWarn 

    • ADEumLoggingLevelError 

    Info

    Verbose、All、Debug レベルのロギングを使用するのは、トラブルシューティングのときだけであり、実稼働では必ずオフにしてください。

    Examples:

    Appd tabs container
    Appd tab item
    tabNameObjective-C
    Code Block
    languagecpp
    -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        // appKey should be assigned your EUM app key
        ADEumAgentConfiguration *config = [[ADEumAgentConfiguration alloc] initWithAppKey: <#EUM_APP_KEY#>];
        config.loggingLevel = ADEumLoggingLevelAll;
        [ADEumInstrumentation initWithConfiguration:config];
        ...
    }
    Appd tab item
    tabNameSwift 4.2
    Code Block
    languageruby
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    {
        // appKey should be assigned your EUM app key
        let config = ADEumAgentConfiguration(appKey: <#EUM_APP_KEY#>)
        config.loggingLevel = .all
        ADEumInstrumentation.initWithConfiguration(config)
        ...
        return true
    }

    Anchor
    ios-sdk
    ios-sdk
    iOS SDK のドキュメント

    最新の iOS SDK ドキュメント、または以下に記載されている以前のバージョンを参照してください。

    Info

    4.5.6 以降、iOS エージェントは、コントローラと他の AppDynamics プラットフォーム コンポーネントとは異なるバージョン番号になりました。すべての iOS エージェント機能を完全にサポートするために必要なコントローラおよび EUM サーバの最小バージョンについては、「モバイル エージェント バージョンおよび展開サポートマトリックス」を参照してください。