iOS API

The Instana iOS API is a set of functions to instrument custom code in your iOS applications to capture data and send it to the Instana backend.

Instana iOS agent API

You can initiate the Instana iOS agent through the Instana class methods.

Setting up the Instana iOS agent

Initialize the Instana iOS agent early in didFinishLaunchingWithOptions by calling the setup function. Do not delay starting of Instana. Make sure to call the setup immediately after the app launch. You can enable or disable Instana delay by using the Instana.collectionEnabled flag.

static func setup(key: String, reportingURL: URL)

Configuration parameters

Parameter Description
key (String) The Instana monitoring configuration key.
reportingURL (URL) The URL pointing to the Instana instance to which the monitoring data is sent.
httpCaptureConfig (HTTPCaptureConfig, optional) By default, HTTP requests and responses are captured automatically. To disable automatic monitoring, set this parameter to manual or use both the modes together with automaticAndManual HTTP capture configuration. To turn off HTTP session monitoring, you can pass none.
collectionEnabled (Bool, optional) By default, the data collection is turned on with the setup. To set up Instana but ignore any data collection, set this parameter to false in the setup. This parameter is useful for scenarios in which user consent is required before the agent can collect data. The default value is true.
enableCrashReporting (Bool, optional) (public preview) By default, the crash reporting is disabled in the setup. The crash reporting can be enabled later by using this property, which allows apps to start collecting Instana crash data. This property is most useful for scenarios in which explicit user consent is required before the agent can collect crash data. The default value is false.
slowSendInterval (Double, optional) This parameter enables slow sending mode feature on beacon sending failure by providing a valid positive number in seconds (range from 2-3600). The default value is 0.0, which means that the slow sending mode is disabled.
usiRefreshTimeIntervalInHrs (Double, optional) This parameter sets the usi (userSessionIdentifier) refresh frequency. You need to provide the value in hours. The default value is -1.0, which means that the user session ID is never refreshed. The following parameter values indicate the status of the usi:

- Negative number: This value indicates that the usi retains its default behavior and never refreshes.
- Positive number: This value indicates that the usi refreshes at the specified time intervals.
- Zero: This value indicates that the usi is not sent to the Instana backend and thus the identifier is deactivated.
autoCaptureScreenNames (Bool, optional) (public preview) This parameter enables automatic capturing of screen names when set to true.
View controllers with UIViewController as superclass, either directly or indirectly, can be auto captured.
For UIKit, view controllers with accessibilityLabel or navigationItem.title set are auto captured. The view name is set as (accessibilityLabel or navigationItem.title) @(ViewControllerClassName). If neither is set, the view name is @(ViewControllerClassName).
For SwiftUI, the view with navigationTitle set is auto captured, otherwise it is ignored.
The default value is false.
debugAllScreenNames (Bool, optional) (public preview) This parameter debugs autoCaptureScreenNames. When debugAllScreenNames is set to true and autoCaptureScreenNames is also set to true, all view controllers are captured.
When autoCaptureScreenNames is set to false, debugAllScreenNames is ignored.
The debugAllScreenNames parameter must be set to false in the production environment. The default value is false.

Example

import InstanaAgent

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    Instana.setup(key: "<Your Instana Key>", reportingURL: URL(string: "<Your Instana URL>")!)
    ....
    return true
}

Manual HTTP capture configuration is shown in the following example. To change the default settings, run the following commands:

let options = InstanaSetupOptions(httpCaptureConfig: .manual)
Instana.setup(key: <Your Key>, reportingURL: <Your Instana URL>, options: options)

Current configuration

The Instana class object contains the following properties to retrieve the current configuration:

Property Description
key (String, optional) The Instana monitoring configuration key.
reportingURL (URL, optional) The URL pointing to the Instana instance to which the monitoring data is sent.

Example

let key = Instana.key
let url = Instana.reportingURL

Session identifier

Each Instana agent instance has a unique session identifier that you can use for other purposes in your app.

Property Description
sessionID (String, optional) The current session identifier. This session ID is created during the setup process.

Example

let sessionID = Instana.sessionID

Automatic HTTP monitoring

By default, HTTP sessions are captured automatically. The Instana iOS agent uses Foundation's NSURLProtocol to monitor HTTP requests and responses. To observe all NSURLSession automatically with NSURLProtocol, some method swizzling in the NSURLSession is necessary. To opt out of automatic HTTP session monitoring, you must capture every request and response manually.

Manual HTTP monitoring

To capture HTTP sessions manually, you must set up Instana by using the httpCaptureConfig: .manual and use the corresponding functions. You can manually capture HTTP requests and responses by using URLRequest or URL.

Automatic and manual HTTP monitoring

To capture HTTP sessions automatically or manually, you must set up Instana by using the httpCaptureConfig: .automaticAndManual. You can use the automatic instrumentation or manually capture HTTP requests and responses.

Start Capture (URLRequest)

The function to start HTTP capture for URLRequest and the optional view name. A HTTPMarker object is returned. This object is required to set the results of the HTTP response.

static func startCapture(_ request: URLRequest?, viewName: String? = nil) -> HTTPMarker
Configuration parameters
Parameter Description
request (URLRequest) URLRequest to capture
viewName (String, optional) The name of the visible view that is related to this request.

Returns: HTTP marker to set the results of the HTTP response (HTTP status code, sizes, error).

Start capture (URL)

This function starts the HTTP capture for the URL, HTTP method, and the optional view name. A HTTPMarker object is returned. You need this object later to set the results of the HTTP response.

static func startCapture(url: URL, method: String, viewName: String? = nil) -> HTTPMarker
Configuration parameters
Parameter Description
url (URL) The URL to capture
method (String) The HTTP method of the request
viewName (String, optional) The name of the visible view that is related to this request

Returns: HTTP marker to set the results of the HTTP response (HTTP status code, sizes, error).

Set HTTP response size

Invoke this method on HTTPMarker when the response size is determined.

func set(responseSize: Instana.Types.HTTPSize)
Configuration parameters
Parameter Description
responseSize (HTTPSize) The httpSize object that contains headerBytes, bodyBytes, and bodyBytesAfterDecoding.

Make sure that you don't call any methods on HTTPMarker after you called finish or cancel.

HTTP response size

You can create HTTPMarker.Size with the following initializer:

init(response: URLResponse, transactionMetrics: [URLSessionTaskTransactionMetrics]?)
Configuration parameters
Parameter Description
response (URLResponse) The URLResponse object
transactionMetrics ([URLSessionTaskTransactionMetrics], optional) An optional array with URLSessionTaskTransactionMetrics

You can also create the HTTPMarker.Size object by passing the size value directly as a parameter:

HTTPMarker.Size(header: Instana.Types.Bytes, body: Instana.Types.Bytes, bodyAfterDecoding: Instana.Types.Bytes)

Finish Capture (URLResponse)

Call finish on HTTPMarker after the request is completed with the URLResponse and an optional Error.

func finish(response: URLResponse?, error: Error?)

Finish Capture (HTTPCaptureResult)

Alternatively you can us HTTPCaptureResult to finish the capture.

let size = HTTPMarker.Size(header: 123, body: 1024, bodyAfterDecoding: 2048)
let result = HTTPCaptureResult(statusCode: statusCode, backendTracingID: "Instana-backend-tracing-id", responseSize: size, error: error)
marker.finish(result: result)

Cancel capture

Invoke this method on HTTPMarker if the request is canceled before completion. The state is set to "failed internally" with the NSURLErrorCancelled status when you call cancel.

func cancel()

Complete manual HTTP monitoring example (URLResponse)

let marker = Instana.startCapture(request, viewName: "User: Details")
URLSession.shared.dataTask(with: request) { data, response, error in
    marker.finish(response: response, error: error)
}.resume()

You can also set the HTTP response size manually through URLSessionDelegate as shown in the following example (before you call finish or cancel):

func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) {
    guard let response = task.response else { return }
    marker.set(responseSize: HTTPMarker.Size(response: response, transactionMetrics: metrics.transactionMetrics))
}

Complete manual HTTP monitoring example (URL)

let url = URL(string: "https://www.example.com/user/123/details")!
let marker = Instana.startCapture(url: url, method: "GET", viewName: "Home")
YourNetworkManager(url: url, method: "GET") { (statusCode, error) in
    let size = HTTPMarker.Size(header: 123, body: 1024, bodyAfterDecoding: 2048) // optionally
    let backendTracingID = "Instana-backend-tracing-id" // optionally
    let result = HTTPCaptureResult(statusCode: statusCode, backendTracingID: backendTracingID, responseSize: size, error: error)
    marker.finish(result: result)
}.resume()

Views

Instana can segment app metrics by logical views. To do so, you need to add a hint on what view the user is looking at currently. This view name can be set by usingsetView(name: String). The view name is attached to all monitored beacons until you call setView again with another name. Do not use technical or generic names like the Class (that is, WebViewController) to define views. Use readable names for views. For example, product detail page or payment selection. It results in fewer pages with a direct relation to the existing code. Consider setting the view name in viewDidAppear. Setting the view name enables Instana to track page transitions in addition to page loads.

The view name is updated automatically when your app changes the state (for example, from active to inactive or background). The view name is Inactive when your app is in inactive state (when it receives an SMS). It is set to Background after your app leaves the foreground.

static func setView(name: String)

Configuration parameters

Parameter Description
name (String) The name of the view

Example

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    Instana.setView(name: "User: Details")
}

To get the current view name, you can use the class variable viewName. The value for view name might be Inactive or Background depending on your app state.

Property Description
viewName (String, optional) The current view name is set through setView(name:).

Example

let viewName = Instana.viewName

Identifying Users

User-specific information can be optionally sent with data that is transmitted to Instana. This information can then be used to unlock more capabilities such as:

  • Calculate the number of users affected by errors
  • Filter data for specific users
  • Find the user that initiated a view change or HTTP request

By default, Instana does not associate any user-identifiable information to beacons. You must check the respective data protection laws before you associate any user-identifiable information to beacons. Identify users with a user ID. For Instana, it is a transparent String that is used only to calculate certain metrics. You can also use userName and userEmail to access more filters to present user information.

If you handle anonymous users and thus don't have access to user IDs you can alternatively use session IDs. Session IDs are not as helpful as user IDs to filter data, but they are good indicators to calculate affected or unique user metrics. Consider setting a username such as Anonymous to clearly distinguish between the authenticated and unauthenticated users. Session IDs can be sensitive data depending on the framework or platform used. Consider hashing session IDs to avoid transmitting data to Instana that can grant access.

Data that is already transmitted to Instana cannot be retroactively updated. Call this API immediately in the app launch process.

static func setUser(id: String, email: String?, name: String?)

Configuration parameters

Parameter Description
id (String) An identifier for the user
email (String, optional) The email address of the user
name (String, optional) The name of the user

You can pass nil for values you don't want to set.

Example

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
     Instana.setup(key: InstanaKey, reportingURL: InstanaURL)
     Instana.setUser(id: someID, email: "email@example.com", name: "John")
     return true
}

Alternatively, you can set the user properties individually.

User ID

Set the user ID:

static func setUser(id: String)
Configuration parameters
Parameter Description
id (String) An identifier for the user

User email address

Set the user email address:

static func setUser(email: String)
Configuration parameters
Parameter Description
email (String) The email address of the user

Username

Set the username:

static func setUser(name: String)

Parameters

Parameter Description
name (String) Name of the user

Metadata

Metadata information is attached to the transmitted data. Consider using metadata to track UI configuration values, settings, feature flag, or any additional context that might be useful for analysis. You should set the metadata in the app launch process to assign the key or values to all transmitted data.

static func setMeta(value: String, key: String)

Parameters

Parameter Description
value (String) The value of the key-value pair you want to add as metadata
key (String) The key of the key-value pair you want to add as metadata

Example

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    Instana.setup(key: InstanaKey, reportingURL: InstanaURL)
    Instana.setMeta(value: "ReactNative", key: "Platform")
    Instana.setMeta(value: "DEBUG", key: "Environment")
    return true
}

Excluding URLSession from monitoring

You can exclude a custom URLSession from being monitored by the Instana iOS agent.

static func ignore(_ session: URLSession)

Configuration parameters

Parameter Description
session (URLSession) URLSession to be excluded from monitoring

Example

let session = URLSession(configuration: .default)
Instana.ignore(session)

Excluding URLs from monitoring

You can exclude URLs that match with the regular expressions to prevent transmission to Instana. A good example for usage of this function would be to exclude all HTTP requests that contain any sensitive data like a password.

static func setIgnoreURLs(matching regex: [NSRegularExpression])

Configuration parameters

Parameter Description
regex ([NSRegularExpression]) An array of NSRegularExpression objects matching the URLs that you want to ignore

Example

let regex = try! NSRegularExpression(pattern: "/.*(&|\?)password=.*/i")
Instana.setIgnoreURLs(matching: [regex])

In the example, all URLs that contain password in the query are ignored.

Alternatively you can ignore complete URLs similar to the following example:

Instana.setIgnore(urls: [URL(string: "https://www.example.com")!])

Report custom events

Custom events enable reporting about nonstandard activities, important interactions, and custom timings to Instana. It can be especially helpful to analyze errors that are not detected (breadcrumbs) and to track more performance metrics.

static func reportEvent(name: String, timestamp: Instana.Types.Milliseconds? = nil, duration: Instana.Types.Milliseconds? = nil, backendTracingID: String? = nil, error: Error? = nil, meta: [String: String]? = nil, viewName: String? = Instana.viewName)

Configuration parameters

Parameter Description
name (String) Defines what kind of events occurred in your app results in the transmission of a custom beacon.
timestamp (Int64, optional) The timestamp in milliseconds when the event is started. If you don't provide a timestamp, the current time is used as the timestamp. If you don't provide a timestamp but set a duration, the timestamp is calculated by subtracting the duration from the current time. (timestamp = current time - duration)
duration (Int64, optional) The duration in milliseconds of how long the event lasted. The default value is zero.
backendTracingID (String, optional) Identifier to create a backend trace for this event.
error (Error, optional) Error object to provide more context.
meta ([String: String], optional) Key - Value data, which can be used to send metadata to Instana just for this singular event.
viewName (String, optional) You can pass a String to group the request to a view. If you send nil, viewName is ignored. Alternatively you can leave out the parameter viewName to use the current view name you set in setView(name: String).
customMetric (Double, optional) Custom metric data with precision up to 4 decimal places. The default value is Double.nan to indicate that customMetric is not set by caller. Do not include sensitive information in this metric.

Examples

Instana.reportEvent(name: "Event-Name")
Instana.reportEvent(name: "Event-Name", viewName: "User: Details")
Instana.reportEvent(name: "Event-Name", timestamp: 1590149955086, duration: 124842, backendTracingID: "some-id", error: NSError(domain: "Some", code: -1, userInfo: nil), meta: ["Key": "Value"], viewName: "User: Details")
Instana.reportEvent(name: "Event-Name", customMetric: 1234.567)

Enabled or disable collection

You can enable data collection at any time during the runtime. It enables the delayed start of the data collection (for example, after user consent).

Property Description
collectionEnabled (Bool) The flag to enable or disable data collection

Example

Instana.collectionEnabled = true

Enable logging

The Instana iOS agent has a logging capability for debugging purposes. Just add the environment variable INSTANA_DEBUG_LOGLEVEL in Xcode. As a value, you must pass one of the following values as the log level:

  • 0 = Debug information, warnings and error,
  • 1 = Warnings and errors,
  • 2 => Errors only

Redact URL Query parameters

Query parameters in the collected URLs might contain sensitive data. Therefore, the Instana iOS agent supports the specification of regex patterns for query parameter keys whose values must be redacted. Any redacted value is replaced with <redacted>. Redaction occurs within the Instana agent before it is reported to Instana. Consequently, secrets do not reach Instana for processing. Secrets are not available to analyze in the UI or retrieve by using Instana API.

By default, the Instana iOS agent is configured with a list of three regex patterns to automatically redact query parameter values for the keys: "password", "key" and "secret". Redaction is applied only to automatically monitored requests and their associated logs. Manually monitored requests are not redacted.

static func redactHTTPQuery(matching regex: [NSRegularExpression])

Configuration parameters

Parameter Description
regex ([NSRegularExpression]) An array of NSRegularExpression objects matching the keys for the values that you want to redact.

Example

let regex = try! NSRegularExpression(pattern: #"pass(word|wort)"#)
Instana.redactHTTPQuery(matching: [regex])

In this example, the values for the HTTP parameter keys "password" or "passwort" are redacted. The captured URL https://example.com/accounts/?password=123&passwort=459 is collected and displayed as https://example.com/accounts/?password=<redacted>&passwort=<redacted>.

The Instana iOS agent does not support treating path parameters (/account/ /status) or matrix parameters (/account;accountId= /status) as secrets.

Capture HTTP header fields

HTTP request and response headers can be captured by the iOS agent. You can use regular expressions to define the keys of the HTTP header fields that the iOS agent needs to capture.

public static func setCaptureHeaders(matching regex: [NSRegularExpression])

Configuration parameters

Parameter Description
regex ([NSRegularExpression]) An array of the NSRegularExpression objects to match the key of HTTP request and response headers that you want to capture.

Example

let regex = try! NSRegularExpression(pattern: #"X-Key"#, options: [.caseInsensitive])
Instana.setCaptureHeaders(matching: [regex])

This example shows HTTP header fields with the key X-Key or X-KEY.

Slow Sending Mode

Optional: You can turn on the slow sending mode feature.

By default, if a beacon sending fails, the Instana agent tries to resend the beacon until the sending is successful. It doesn't work well with some cellular networks. By enabling the slow sending mode feature, the beacon sending interval is changed to the time value that is assigned to the slowSendInterval parameter. Each sending attempt consists of only one beacon instead of a batch (a maximum 100 beacons in a batch). Instana agent stays in slow sending mode until one beacon is sent successfully.

The valid time range for slowSendInterval is 2-3600 in seconds.

Example

import InstanaAgent
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    let options = InstanaSetupOptions(slowSendInterval: 60.0)
    if !Instana.setup(key: InstanaKey, reportingURL: InstanaURL, options: options) {
        // Error handling here
    }
    ....
    return true
}

User session ID

By default, the user session is tracked. The ID is a randomly generated Universally Unique Identifier (UUID). This ID remains unchanged while the app is installed. You can configure the expiration time of the user session ID by using the usiRefreshTimeIntervalInHrs parameter.

The following parameter values indicate the status of the user session ID:

  • Negative number: The user session ID never expires. This is the default setting. The default value is -1.
  • Positive number: The user session ID is refreshed after the set time, that is, a new UUID is generated and used.
  • Zero: The user session ID is disabled. This value is denoted by 0.0.

Example

import InstanaAgent
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    let options = InstanaSetupOptions(usiRefreshTimeIntervalInHrs: 24.0)
    if !Instana.setup(key: InstanaKey, reportingURL: InstanaURL, options: options) {
        // Error handling here
    }
    ....
    return true
}

Privacy manifest file

Privacy manifest file is supported since iOSAgent version 1.8.0. No extra configuration is needed to use this feature if the app complies with Apple requirements.