Send Real User Monitoring data to Datadog from your iOS applications with Datadog’s dd-sdk-ios
client-side RUM SDK and leverage the following features:
Declare the library as a dependency, depending on your package manager. See Datadog’s Releases page for the latest beta version.
You can use CocoaPods to install dd-sdk-ios
:
pod 'DatadogSDK'
To integrate the SDK using Apple’s Swift Package Manager, add the following as a dependency to your Package.swift
:
.package(url: "https://github.com/DataDog/dd-sdk-ios.git", .upToNextMajor(from: "1.0.0"))
You can use Carthage to install dd-sdk-ios
:
github "DataDog/dd-sdk-ios"
Initialize the library with your application context and your Datadog client token. For security reasons, you must use a client token: you cannot use Datadog API keys to configure the dd-sdk-ios
library as they would be exposed client-side in the iOS application IPA byte code. For more information about setting up a client token, see the client token documentation. You also need to provide an Application ID (create a Javascript RUM application as explained in the RUM Getting Started page).
Datadog.initialize(
appContext: .init(),
configuration: Datadog.Configuration
.builderUsing(
rumApplicationID: "<rum_application-id>",
clientToken: "<client_token>",
environment: "<environment_name>"
)
.set(serviceName: "app-name")
.build()
)
Datadog.initialize(
appContext: .init(),
configuration: Datadog.Configuration
.builderUsing(
rumApplicationID: "<rum_application-id>",
clientToken: "<client_token>",
environment: "<environment_name>"
)
.set(serviceName: "app-name")
.set(endpoint: .eu)
.build()
)
Configure and register the RUM Monitor. You only need to do it once, usually in your AppDelegate
code:
import Datadog
Global.rum = RUMMonitor.initialize()
The RUM SDK offers two instrumentation methods:
Note: It is possible to mix both methods.
To enable RUM views tracking, use the .trackUIKitRUMViews()
option when configuring the SDK:
Datadog.Configuration
.builderUsing(...)
.trackUIKitRUMViews()
.build()
Global.rum = RUMMonitor.initialize()
To customize RUM views tracking, use .trackUIKitRUMViews(using: predicate)
and provide your own implementation of the predicate
which conforms to UIKitRUMViewsPredicate
protocol:
public protocol UIKitRUMViewsPredicate {
func rumView(for viewController: UIViewController) -> RUMView?
}
Inside the rumView(for:)
implementation, your app should decide if a given UIViewController
instance should start the RUM view or not (and return nil
in this case). The returned value of RUMView
should specify at least the path
for created the RUM view. Refer to code documentation comments for more details.
Note: The SDK calls rumView(for:)
many times while your app is running. Your implementation of the predicate should not depend on the order of SDK calls.
To enable RUM resources tracking, use the .track(firstPartyHosts:)
option when configuring the SDK:
Datadog.Configuration
.builderUsing(...)
.track(firstPartyHosts: ["your.domain.com"])
.build()
Global.rum = RUMMonitor.initialize()
Also, assign DDURLSessionDelegate()
as a delegate
of the URLSession
you want to monitor, for example:
let session = URLSession(
configuration: .default,
delegate: DDURLSessionDelegate(),
delegateQueue: nil
)
This will make the SDK track requests sent from this instance of the URLSession
. Requests whose URLs match the firstPartyHosts
will be additionally marked as “first party” in the RUM Explorer.
To enable RUM actions tracking, use the .trackUIKitActions()
option when configuring the SDK:
Datadog.Configuration
.builderUsing(...)
.trackUIKitActions()
.build()
Global.rum = RUMMonitor.initialize()
This makes the SDK track all significant taps occurring in the app. For privacy reasons, all interactions with the on-screen keyboard are ignored.
All “error” and “critical” logs are be reported as RUM errors and linked to the current RUM view:
logger.error("message")
logger.critical("message")
Similarly, all ended APM spans marked as error are be reported as RUM errors:
span.setTag(key: OTTags.error, value: true)
Use the following methods on Global.rum
to manually collect RUM resources:
.startView(viewController:)
.stopView(viewController:)
Example:
// in your `UIViewController`:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
Global.rum.startView(viewController: self)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
Global.rum.stopView(viewController: self)
}
For more details and available options, refer to the code documentation comments in DDRUMMonitor
class.
Use the following methods on Global.rum
to manually collect RUM resources:
.startResourceLoading(resourceKey:request:)
.stopResourceLoading(resourceKey:response:)
.stopResourceLoadingWithError(resourceKey:error:)
.stopResourceLoadingWithError(resourceKey:errorMessage:)
Example:
// in your network client:
Global.rum.startResourceLoading(
resourceKey: "resource-key",
request: request
)
Global.rum.stopResourceLoading(
resourceKey: "resource-key",
response: response
)
Note: The String
used for resourceKey
in both calls must be unique for the resource you are calling. This is necessary for the SDK to match a resource’s start with its completion.
For more details and available options, refer to the code documentation comments in DDRUMMonitor
class.
To manually register instantaneous RUM actions (e.g: .tap
), use:
.addUserAction(type:name:)
or for continuous RUM actions (e.g: .scroll
), use:
.startUserAction(type:name:)
.stopUserAction(type:)
on Global.rum
.
Example:
// in your `UIViewController`:
@IBAction func didTapDownloadResourceButton(_ sender: Any) {
Global.rum.addUserAction(
type: .tap,
name: (sender as? UIButton).currentTitle ?? "",
)
}
Note: When using .startUserAction(type:name:)
and .stopUserAction(type:)
, the action type
must be the same. This is necessary for the SDK to match a resource’s start with its completion.
For more details and available options, refer to the code documentation comments in DDRUMMonitor
class.
Use the following methods on Global.rum
to manually collect RUM errors:
.addError(message:)
.addError(error:)
Example:
// anywhere in your code:
Global.rum.addError(message: "error message.")
For more details and available options, refer to the code documentation comments in DDRUMMonitor
class.