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.
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 Data||Description||Specifications||Where Data is Displayed|
|Info points||How often a method is invoked, and how long it takes to run.|
|Custom timers||Any arbitrary sequence of events within your code timed, |
even spanning multiple methods.
|Custom metrics||Any integer-based data you wish to collect.|
|User data||Any string key/value pair you think might be useful.|
|Breadcrumbs||The context for a crash.|
|User interaction||Capture when users press buttons, click on lists, and select text.|
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.
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
endCall, something like the following:
Custom timers allow you to time any arbitrary sequence of events within your code, even spanning multiple methods, by using
stopTimer. For example, to track the time a user spends viewing a screen, the instrumentation could look like this:
This information appears in the Custom Data view of the Controller UI.
startTimerWithName again with the same name value resets a named timer.
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:
This information appears in the Custom Data view of the Controller UI.
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.
You can also set user data with values of other types (Long, Boolean, Double, Date) using the following methods:
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:
Using this method means that breadcrumbs are reported in crash reports only.
mode is either:
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.
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:
This callback is invoked on your app's UI thread, so any significant work should be done on a separate work thread.
ADEumCrashReportSummary passed in has the following properties:
If you are sending the information to another analytics tool, such as Google Analytics, it is best to include all five properties:
exceptionReasonare 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.
signalCodeare useful for quick identification of the crash. These are from the system and are independent of the runtime.
For additional information,
crashIdcan 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:
You set the object that implements the
ADEumCrashReportCallback protocol during agent configuration:
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.
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 Signature||Description|
(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.
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
(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
To report the error without the stack trace, set
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.
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.
reportErroris not passed the argument
andStackTrace, by default, the stack trace is automatically included with the error.
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.
Report Stack Traces with ANRs
In addition to enabling ANR detection, you set the property
YES (Objective-C) or
true (Swift) to report stack traces with the ANRs.
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.
Configure Hybrid Application Support
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.
Runtime Configuration for Hybrid Application Support
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
The table below describes the supported properties and provides the default value for the
If the client receives a
The injection occurs during the creation of a new WKWebView. So, if a WKWebView is created when this flag is set to
|false||When set to |
|When set to |
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:
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.
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.
The following are common use cases for the
ViewControllerperforms 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.
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.
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.
Rename the session frame name. You call this method from the
End the session frame. You call this method from the
|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.|
|Rename the session frame name. You call this method from the |
|End the session frame. You call this method from the |
Session Frame Example
In the following example, the
SessionFrame API is used to track user activity during the checkout process.
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.
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.
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
- To set headers to allow correlation with server-side processing, use the
- To configure the agent to use your custom library to deliver its beacons over HTTP, use the
ADEumCollectorChannelprotocol and the
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.
You must initialize the agent using one of the
initWithKey methods before using this method.
url is the URL being requested. This parameter must not be
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
Properties to be set
The following properties should be set on the
requestTrackerWithURL object to describe to the agent the results of the call.
Indicates the failure to receive a response, if this occurred. If the request was successful, this should be
If a response was received, this should be an integer.
If an error occurred and a response was not received, this should be
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
Given a request snippet like this:
Adding the tracker could look something like this:
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.
This is done automatically for standard HTTP libraries.
generatemethod and set the generated headers before sending a request to the backend.
Report back the response headers, using the allHeaderFields property shown above.
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.
Implement a class that conforms to this protocol:
ADEumInstrumentation, passing in an instance of your class that implements
ADEumCollectorChannel. See the latest iOS SDK documentation for more information.
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
Security 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.
You can also configure the iOS Agent to only capture one type of user interaction:
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:
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 ADEum
AgentConfiguration object to
NO for Objective-C and
false for Swift as shown below.
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.
ADEumInstrumentation class provides the methods
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.
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:
- Implement a network request callback that modifies or ignores specific URLs.
- Register the network request callback in the initialization code.
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.
networkRequestCallback method, in general, should follow the steps below to transform URLs:
- Identify specific URLs using techniques such as regex or pattern matching.
- Modify the
urlproperty of the
ADEumHTTPRequestTrackerobject. (Modifying other properties of the
ADEumHTTPRequestTrackerobject will be ignored.)
- Assign a valid URL to the
The first step is optional as you could choose to transform the URLs of all network requests.
networkRequestCallback method returns
false, the beacon is dropped. The general process for ignoring beacons is as follows:
Identify specific URLs using techniques such as regex or pattern matching.
You could theoretically ignore all network requests by having the callback
networkRequestCallback always return
NO (Objective-C) or
false(Swift) to ignore the network request as implied by this example.
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
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:
Use verbose, all, and debug levels of logging only for troubleshooting and be sure to turn off for production.
See the latest iOS SDK documentation or the previous versions listed below: 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.
iOS SDK Documentation
See the latest iOS SDK documentation or the previous versions listed below:
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.