---
title: Upgrade RUM Mobile SDKs
description: >-
  Migration guide for upgrading between major versions of RUM, Logs, and Trace
  mobile SDKs with breaking changes and new features.
breadcrumbs: >-
  Docs > RUM & Session Replay > Real User Monitoring & Session Replay Guides >
  Upgrade RUM Mobile SDKs
---

# Upgrade RUM Mobile SDKs

## Overview{% #overview %}

Follow this guide to migrate between major versions of the Mobile RUM, Logs, and Trace SDKs. See each SDK's documentation for details on its features and capabilities.

**Most common migrations**:

- **v2 to v3**: Focus on Open Tracing removal and API updates
- **v1 to v2**: Major architectural changes to modular design

## From v2 to v3{% #from-v2-to-v3 %}

{% tab title="Android" %}
The transition from version 2 to version 3 focuses on removing support for the legacy Open Tracing project, improving the stability and consistency of the SDK.
{% /tab %}

{% tab title="iOS" %}
The migration from v2 to v3 focuses on streamlining modules, refining defaults, and improving reliability across product features.

All SDK products (RUM, Trace, Logs, Session Replay, and so on) remain modular and separated into distinct libraries. The main change is that the `DatadogObjc` module has been removed, with its contents integrated into the corresponding product modules.
{% /tab %}

{% tab title="React Native" %}
The migration from v2 to v3 focuses on aligning configuration with the v3 modular SDK behavior and consolidating configuration ownership across `CoreConfiguration`, `RumConfiguration`, `LogsConfiguration`, and `TraceConfiguration`.

Please read [the MIGRATION.md guide](https://github.com/DataDog/dd-sdk-reactnative/blob/develop/MIGRATION.md) in the official React Native repository for the full list of changes.

{% alert level="warning" %}
**Important:** Unlike v2.x (which would always enable all feature modules when initializing the SDK), v3 does **not** initialize or enable a feature module unless you explicitly pass configuration for it.
{% /alert %}

{% /tab %}

### Modules{% #modules %}

{% tab title="Android" %}

{% alert level="danger" %}
Datadog follows Google's [AndroidX library version policy](https://developer.android.com/jetpack/androidx/versions#version-table) for the `AndroidX` libraries so the minimum Android API level supported by SDK v3 is `23`.
{% /alert %}

**Requirements**:

- Kotlin 1.9 is required
- The `Open Tracing` dependency was removed because it is obsolete

{% /tab %}

{% tab title="iOS" %}
Libraries continue to be modularized in v3. Adopt the following libraries:

- `DatadogCore`
- `DatadogCrashReporting`
- `DatadogLogs`
- `DatadogRUM`
- `DatadogSessionReplay`
- `DatadogTrace`
- `DatadogWebViewTracking`

{% collapsible-section %}
## SPM (Recommended)

```swift
let package = Package(
  ...
  dependencies: [
      .package(url: "https://github.com/DataDog/dd-sdk-ios", from: "3.0.0")
  ],
  targets: [
      .target(
          ...
          dependencies: [
              .product(name: "DatadogCore", package: "dd-sdk-ios"),
              .product(name: "DatadogCrashReporting", package: "dd-sdk-ios"),
              .product(name: "DatadogLogs", package: "dd-sdk-ios"),
              .product(name: "DatadogRUM", package: "dd-sdk-ios"),
              .product(name: "DatadogSessionReplay", package: "dd-sdk-ios"),
              .product(name: "DatadogTrace", package: "dd-sdk-ios"),
              .product(name: "DatadogWebViewTracking", package: "dd-sdk-ios"),
          ]
      ),
  ]
)
```

{% /collapsible-section %}

{% collapsible-section %}
## CocoaPods

```ruby
pod 'DatadogCore'
pod 'DatadogCrashReporting'
pod 'DatadogLogs'
pod 'DatadogRUM'
pod 'DatadogSessionReplay'
pod 'DatadogTrace'
pod 'DatadogWebViewTracking'
```

{% /collapsible-section %}

{% collapsible-section %}
## Carthage

The `Cartfile` stays the same:

```
github "DataDog/dd-sdk-ios"
```

In Xcode, you **must** link the following frameworks:

```
DatadogInternal.xcframework
DatadogCore.xcframework
```

Then, you can select the modules you want to use:

```
DatadogCrashReporting.xcframework
DatadogLogs.xcframework
DatadogRUM.xcframework
DatadogSessionReplay.xcframework
DatadogTrace.xcframework
DatadogWebViewTracking.xcframework
```

{% /collapsible-section %}

{% /tab %}

{% tab title="React Native" %}
See [the MIGRATION.md guide](https://github.com/DataDog/dd-sdk-reactnative/blob/develop/MIGRATION.md) in the official React Native repository for the recommended upgrade steps and any required dependency updates.

{% alert level="warning" %}
**Important:** In v3, feature modules are only enabled if you pass their configuration during initialization (for example, RUM / Logs / Trace). If you omit a feature configuration, that feature is not initialized or enabled.
{% /alert %}

{% /tab %}

### Required changes and API updates{% #required-changes-and-api-updates %}

{% tab title="Android" %}
### Core{% #core %}

{% alert level="info" %}
**Action Required:** In SDK v3, the user info ID becomes mandatory, and the `null` value cannot be provided anymore.
{% /alert %}

API changes:

| `2.x`                                                         | `3.0`                                                              |
| ------------------------------------------------------------- | ------------------------------------------------------------------ |
| `Datadog.setUserInfo(null, "Jane Smith", "jane@example.com")` | `Datadog.setUserInfo("user123", "Jane Smith", "jane@example.com")` |

### RUM{% #rum %}

We made minor improvements to the RUM modules. They don't require significant changes to your code, but it's worth checking if you can refactor some redundant parameters.

The URL provided in the `useCustomEndpoint` method should be the full endpoint URL (`https://example.com/rum/upload`), not just the hostname:

```kotlin
Rum.enable(
  RumConfiguration.Builder(...)
      .useCustomEndpoint("https://example.com/rum/upload")
      .build()
)
```

API changes:

| `2.x`                                                                               | `3.0`                                                                                |
| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `DatadogRumMonitor.startResource(String, String, String,Map<String, Any?>)`         | Use `startResource` method which takes `RumHttpMethod` as `method` parameter instead |
| `com.datadog.android.rum.GlobalRum`                                                 | `GlobalRum` object was renamed to `com.datadog.android.rum.GlobalRumMonitor`         |
| `com.datadog.android.rum.RumMonitor.addAction()`                                    | Parameter `attributes: Map<String, Any?>` is optional                                |
| `com.datadog.android.rum.RumMonitor.startAction()`                                  | Parameter `attributes: Map<String, Any?>` is optional                                |
| `com.datadog.android.rum.RumMonitor.stopResource()`                                 | Parameter `attributes: Map<String, Any?>` is optional                                |
| `com.datadog.android.rum.RumMonitor.addError()`                                     | Parameter `attributes: Map<String, Any?>` is optional                                |
| `com.datadog.android.rum.RumMonitor.addErrorWithStacktrace()`                       | Parameter `attributes: Map<String, Any?>` is optional                                |
| `com.datadog.android.rum.internal.monitor.AdvancedNetworkRumMonitor.stopResource()` | Parameter `attributes: Map<String, Any?>` is optional                                |
| `com.datadog.android.rum.internal.monitor.AdvancedNetworkRumMonitor.stopResource()` | Parameter `attributes: Map<String, Any?>` is optional                                |

### Logs{% #logs %}

The Logs product no longer reports fatal errors. To enable Error Tracking for crashes, Crash Reporting must be enabled in conjunction with RUM.

The URL provided in the `useCustomEndpoint` method should be the full endpoint URL (`https://example.com/logs/upload`), not just the hostname:

```kotlin
Logs.enable(
  LogsConfiguration.Builder()
      .useCustomEndpoint("https://example.com/logs/upload")
      .build()
)
```

### Trace{% #trace %}

The URL provided in the `useCustomEndpoint` method should be the full endpoint URL (e.g.: `https://example.com/trace/upload`), not just the hostname, i.e:

```kotlin
Trace.enable(
  TraceConfiguration.Builder()
      .useCustomEndpoint(`https://example.com/trace/upload`)
      .build()
)
```

The [`Open Tracing`](https://opentracing.io/) project has been marked as archived and it is no longer supported. The `Open Tracing` dependencies on has been removed from SDK v3.

The Datadog SDK already supports [`Open Telemetry`](https://opentelemetry.io/), which is the recommended way to use the tracing feature API.

**Note** that the `Open Telemetry` specification library [requires](https://github.com/open-telemetry/opentelemetry-java?tab=readme-ov-file#requirements) desugaring to be enabled for projects with a `minSdk` < 26.

#### Migrating tracing from `Open Tracing` to `Open Telemetry` (recommended){% #migrating-tracing-from-open-tracing-to-open-telemetry-recommended %}

1. Add the `Open Telemetry` dependency to your `build.gradle.kts`:

```kotlin
implementation(project("com.datadoghq:dd-sdk-android-trace-otel:x.x.x"))
```
Replace the `Open Tracing` configuration:
```kotlin
GlobalTracer.registerIfAbsent(
  AndroidTracer.Builder()
    .setService(BuildConfig.APPLICATION_ID)
    .build()
)
```

with the `Open Telemetry` configuration:

```kotlin
GlobalOpenTelemetry.set(
  DatadogOpenTelemetry(BuildConfig.APPLICATION_ID)
)
```

To access the tracer object for manual (custom) tracing, use `io.opentelemetry.api.GlobalOpenTelemetry.get()` instead of `io.opentracing.util.GlobalTracer.get()`. For example:

```kotlin
val tracer: Tracer = GlobalOpenTelemetry
  .get()
  .getTracer("SampleApplicationTracer")

val span = tracer
  .spanBuilder("Executing operation")
  .startSpan()

// Code that should be instrumented

span.end()
```

Refer to the official `Open Telemetry` [documentation](https://opentelemetry.io/docs/) for more details.

#### Migrating tracing from `Open Tracing` to `DatadogTracing` (transition period){% #migrating-tracing-from-open-tracing-to-datadogtracing-transition-period %}

{% alert level="danger" %}
This option has been added for compatibility and to simplify the transition from Open Tracing to Open Telemetry, but it may not be available in future major releases. Datadog recommends using Open Telemetry as the standard for tracing tasks. However, if it is not possible to enable desugaring in your project for some reason, you can use this method.
{% /alert %}
Replace the `Open Tracing` configuration: ```kotlin GlobalTracer.registerIfAbsent( AndroidTracer.Builder() .setService(BuildConfig.APPLICATION_ID) .build() ) ```
with the `DatadogTracing` configuration:

```kotlin
GlobalDatadogTracer.registerIfAbsent(
  DatadogTracing.newTracerBuilder()
    .build()
)
```

For manual (custom) tracing use `com.datadog.android.trace.GlobalDatadogTracer.get()` instead of `io.opentracing.util.GlobalTracer.get()` to access the tracer object. For example:

```kotlin
val tracer = GlobalDatadogTracer.get()

val span = tracer
  .buildSpan("Executing operation")
  .start()

// Code that should be instrumented

span.finish()
```

Refer to the Datadog [documentation](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/android?tab=kotlin) for more details.

API changes:

| `2.x`                                     | `3.0` `Open Telemetry`                     | `3.0` `Datadog API`                                     |
| ----------------------------------------- | ------------------------------------------ | ------------------------------------------------------- |
| `io.opentracing.util.GlobalTracer`        | `io.opentelemetry.api.GlobalOpenTelemetry` | `com.datadog.android.trace.GlobalDatadogTracer`         |
| `com.datadog.android.trace.AndroidTracer` | `io.opentelemetry.api.trace.Tracer`        | `com.datadog.android.trace.api.tracer.DatadogTracer`    |
| `io.opentracing.Span`                     | `io.opentelemetry.api.trace.Span`          | `com.datadog.android.trace.api.span.DatadogSpan`        |
| `io.opentracing.Scope`                    | `io.opentelemetry.context.Scope`           | `com.datadog.android.trace.api.scope.DatadogScope`      |
| `io.opentracing.SpanContext`              | `io.opentelemetry.api.trace.SpanContext`   | `com.datadog.android.trace.api.span.DatadogSpanContext` |

Replacement hints:

| `2.x`                                         | `3.0` `Open Telemetry`                                | `3.0` `Datadog API`                               |
| --------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------- |
| `AndroidTracer.Builder().build()`             | `DatadogTracing.newTracerBuilder().build()`           |
| `AndroidTracer.setPartialFlushThreshold(Int)` | `OtelTracerProvider.setPartialFlushThreshold()`       | `DatadogTracerBuilder.withPartialFlushMinSpans()` |
| `io.opentracing.SpanContext.toTraceId()`      | `io.opentelemetry.api.trace.SpanContext.getTraceId()` | `DatadogSpanContext.traceId.toString()`           |
| `io.opentracing.Span.setError()`              | `io.opentelemetry.api.trace.recordException()`        | `DatadogSpan.addThrowable()`                      |

### OkHttp instrumentation{% #okhttp-instrumentation %}

The OkHttp instrumentation (`com.datadoghq:dd-sdk-android-okhttp:x.x.x`) does not require desugaring support. However, a few migration actions may be necessary.

API changes:

| `2.x`                                                                                                                                  | `3.0`                                       |
| -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| `TracingInterceptor(String, List<String>, TracedRequestListener,Sampler<Span>)`                                                        | Use `TracingInterceptor.Builder()` instead. |
| `TracingInterceptor(String?,Map<String, Set<TracingHeaderType>>, TracedRequestListener, Sampler<Span>)`                                | Use `TracingInterceptor.Builder()` instead. |
| `TracingInterceptor(String?,TracedRequestListener,Sampler<Span>)`                                                                      | Use `TracingInterceptor.Builder()` instead. |
| `DatadogInterceptor(String?, Map<String, Set<TracingHeaderType>>,TracedRequestListener, RumResourceAttributesProvider, Sampler<Span>)` | Use `DatadogInterceptor.Builder()` instead. |
| `DatadogInterceptor(String?,List<String>,TracedRequestListener,RumResourceAttributesProvider,Sampler<Span>)`                           | Use `DatadogInterceptor.Builder()` instead. |
| `DatadogInterceptor(String?,TracedRequestListener,RumResourceAttributesProvider,Sampler<Span>)`                                        | Use `DatadogInterceptor.Builder()` instead. |

### Session Replay{% #session-replay %}

The URL provided in the `useCustomEndpoint` method should be the full endpoint URL (e.g.: `https://example.com/session_replay/upload`), not just the hostname, i.e:

```kotlin
SessionReplay.enable(
  SessionReplayConfiguration.Builder(...)
      .useCustomEndpoint("https://example.com/session_replay/upload")
      .build()
)
```

{% /tab %}

{% tab title="iOS" %}
The SDK should be initialized as early as possible in the app lifecycle, specifically in the `AppDelegate`'s `application(_:didFinishLaunchingWithOptions:)` callback. This ensures accurate measurement of all metrics, including application startup duration. For apps built with SwiftUI, use `@UIApplicationDelegateAdaptor` to access the `AppDelegate`.

```swift
import DatadogCore

Datadog.initialize(
    with: Datadog.Configuration(
        clientToken: "<client token>",
        env: "<environment>",
        service: "<service name>"
    ),
    trackingConsent: .granted
)
```

**Note**: Initializing the SDK elsewhere (for example later during view loading) may result in inaccurate or missing telemetry, especially around app startup performance.

{% alert level="info" %}
**Action Required:** The API to set the user info requires the `id` parameter, which was optional in 2.x.
{% /alert %}

| `2.x`                                                                         | `3.0`                                                                               |
| ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| `Datadog.setUserInfo(id: nil, name: "Jane Smith", email: "jane@example.com")` | `Datadog.setUserInfo(id: "user123", name: "Jane Smith", email: "jane@example.com")` |

### RUM{% #rum %}

RUM View-level attributes are automatically propagated to all related child events, including resources, user actions, errors, and long tasks. This ensures consistent metadata across events, making it easier to filter and correlate data on Datadog dashboards.

To manage View level attributes more effectively, new APIs were added:

- `Monitor.addViewAttribute(forKey:value:)`
- `Monitor.addViewAttributes(_:)`
- `Monitor.removeViewAttribute(forKey:)`
- `Monitor.removeViewAttributes(forKeys:)`

Other notable changes:

- All Objective-C RUM APIs are included in `DatadogRUM`. The separate `DatadogObjc` module is no longer available.
- App Hangs and Watchdog terminations are no longer reported from app extensions or widgets.
- A new property `trackMemoryWarnings` was added to `RUM.Configuration` to report memory warnings as RUM Errors.

API changes:

| `2.x`                       | `3.0`                                        |
| --------------------------- | -------------------------------------------- |
| -                           | `RUM.Configuration.trackMemoryWarnings`      |
| `RUMView(path:attributes:)` | `RUMView(name:attributes:isUntrackedModal:)` |
| -                           | `Monitor.addViewAttribute(forKey:value:)`    |
| -                           | `Monitor.addViewAttributes(:)`               |
| -                           | `Monitor.removeViewAttribute(forKey:)`       |
| -                           | `Monitor.removeViewAttributes(forKeys:)`     |

### Logs{% #logs %}

The Logs product no longer reports fatal errors. To enable Error Tracking for crashes, Crash Reporting must be enabled in conjunction with RUM.

Additionally, all Objective-C Logs APIs are included in `DatadogLogs`. The separate `DatadogObjc` module is no longer available.

### Trace{% #trace %}

Trace sampling is now deterministic when used alongside RUM. It uses the RUM `session.id` to ensure consistent sampling.

Also:

- The `Trace.Configuration.URLSessionTracking.FirstPartyHostsTracing` configuration sets sampling for all requests by default and the trace context is injected only into sampled requests.
- All Objective-C Trace APIs are included in `DatadogTrace`. The separate `DatadogObjc` module is no longer available.

**Note**: A similar configuration exists in `RUM.Configuration.URLSessionTracking.FirstPartyHostsTracing`.

### Session Replay{% #session-replay %}

Privacy settings are more granular. The previous `defaultPrivacyLevel` parameter has been replaced with:

- `textAndInputPrivacyLevel`
- `imagePrivacyLevel`
- `touchPrivacyLevel`

Learn more about [privacy levels](https://docs.datadoghq.com/session_replay/mobile/privacy_options?platform=ios).

API changes:

| `2.x`                                                                                                         | `3.0`                                                                                                                                                               |
| ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SessionReplay.Configuration(replaySampleRate:defaultPrivacyLevel:startRecordingImmediately:customEndpoint:)` | `SessionReplay.Configuration(replaySampleRate:textAndInputPrivacyLevel:imagePrivacyLevel:touchPrivacyLevel:startRecordingImmediately:customEndpoint:featureFlags:)` |
| `SessionReplay.Configuration(replaySampleRate:defaultPrivacyLevel:startRecordingImmediately:customEndpoint:)` | `SessionReplay.Configuration(replaySampleRate:textAndInputPrivacyLevel:imagePrivacyLevel:touchPrivacyLevel:startRecordingImmediately:customEndpoint:featureFlags:)` |

### URLSession Instrumentation{% #urlsession-instrumentation %}

To enable URLSession Instrumentation, make sure to also enable RUM and/or Trace to report to those products respectively.

Legacy delegate types have been replaced by a unified instrumentation API:

| `2.x`                         | `3.0`                                     |
| ----------------------------- | ----------------------------------------- |
| `DatadogURLSessionDelegate()` | `URLSessionInstrumentation.enable(with:)` |
| `DDURLSessionDelegate()`      | `URLSessionInstrumentation.enable(with:)` |
| `DDNSURLSessionDelegate()`    | `URLSessionInstrumentation.enable(with:)` |

{% /tab %}

{% tab title="React Native" %}
Please read [the MIGRATION.md guide](https://github.com/DataDog/dd-sdk-reactnative/blob/develop/MIGRATION.md) in the official React Native repository.

{% alert level="warning" %}
**Important:** Unlike v2.x (which would always enable all feature modules when initializing the SDK), v3 does **not** initialize or enable a feature module unless you explicitly pass configuration for it.
{% /alert %}

### Configuration changes{% #configuration-changes %}

Certain configuration properties have been moved, renamed, removed, or split:

| Property                      | New Location        | Changes                                                                                               |
| ----------------------------- | ------------------- | ----------------------------------------------------------------------------------------------------- |
| `sampleRate`                  | *Removed*           | Deprecated property removed.                                                                          |
| `sessionSamplingRate`         | `RumConfiguration`  | Moved and renamed to `sessionSampleRate`.                                                             |
| `resourceTracingSamplingRate` | `RumConfiguration`  | Moved and renamed to `resourceTraceSampleRate`.                                                       |
| `proxyConfig`                 | `CoreConfiguration` | Renamed to `proxyConfiguration`.                                                                      |
| `serviceName`                 | `CoreConfiguration` | Renamed to `service`.                                                                                 |
| `customEndpoints`             | *Split*             | Split into `customEndpoint` within `RumConfiguration`, `LogsConfiguration`, and `TraceConfiguration`. |
| *(New property)*              | `CoreConfiguration` | `attributeEncoders` added.                                                                            |
| *(New property)*              | `RumConfiguration`  | `trackMemoryWarnings` added.                                                                          |
| `nativeCrashReportEnabled`    | `RumConfiguration`  | Moved.                                                                                                |
| `nativeViewTracking`          | `RumConfiguration`  | Moved.                                                                                                |
| `nativeInteractionTracking`   | `RumConfiguration`  | Moved.                                                                                                |
| `firstPartyHosts`             | `RumConfiguration`  | Enforced usage of `FirstPartyHost[]` type and moved.                                                  |
| `telemetrySampleRate`         | `RumConfiguration`  | Moved.                                                                                                |
| `nativeLongTaskThresholdMs`   | `RumConfiguration`  | Moved.                                                                                                |
| `longTaskThresholdMs`         | `RumConfiguration`  | Moved.                                                                                                |
| `vitalsUpdateFrequency`       | `RumConfiguration`  | Moved.                                                                                                |
| `trackFrustrations`           | `RumConfiguration`  | Moved.                                                                                                |
| `trackBackgroundEvents`       | `RumConfiguration`  | Moved.                                                                                                |
| `bundleLogsWithRum`           | `LogsConfiguration` | Moved.                                                                                                |
| `bundleLogsWithTraces`        | `LogsConfiguration` | Moved.                                                                                                |
| `trackNonFatalAnrs`           | `RumConfiguration`  | Moved.                                                                                                |
| `appHangThreshold`            | `RumConfiguration`  | Moved.                                                                                                |
| `initialResourceThreshold`    | `RumConfiguration`  | Moved.                                                                                                |
| `trackWatchdogTerminations`   | `RumConfiguration`  | Moved.                                                                                                |
| `actionNameAttribute`         | `RumConfiguration`  | Moved.                                                                                                |
| `logEventMapper`              | `LogsConfiguration` | Moved.                                                                                                |
| `errorEventMapper`            | `RumConfiguration`  | Moved.                                                                                                |
| `resourceEventMapper`         | `RumConfiguration`  | Moved.                                                                                                |
| `actionEventMapper`           | `RumConfiguration`  | Moved.                                                                                                |
| `useAccessibilityLabel`       | `RumConfiguration`  | Moved.                                                                                                |
| `trackInteractions`           | `RumConfiguration`  | Moved.                                                                                                |
| `trackResources`              | `RumConfiguration`  | Moved.                                                                                                |
| `trackErrors`                 | `RumConfiguration`  | Moved.                                                                                                |

### Renamed structures{% #renamed-structures %}

| `2.x`                | `3.x`               |
| -------------------- | ------------------- |
| `DdSdkConfiguration` | `CoreConfiguration` |

### API updates{% #api-updates %}

In addition to configuration ownership changes (Core vs feature configs), several public types and APIs were renamed or relocated to match the v3 modular design. See [the MIGRATION.md guide](https://github.com/DataDog/dd-sdk-reactnative/blob/develop/MIGRATION.md) for the authoritative list and code examples.
{% /tab %}

## From v1 to v2{% #from-v1-to-v2 %}

{% tab title="Android" %}
The migration from v1 to v2 represents a migration from a monolith SDK into a modular architecture. RUM, Trace, Logs, Session Replay, and so on each have individual modules, allowing you to integrate only what is needed into your application.

SDK v2 offers a unified API layout and naming alignment between the iOS SDK, the Android SDK, and other Datadog products.

SDK v2 enables the usage of [Mobile Session Replay](https://docs.datadoghq.com/session_replay/mobile/) on Android and iOS applications.
{% /tab %}

{% tab title="iOS" %}
The migration from v1 to v2 represents a migration from a monolith SDK into a modular architecture. RUM, Trace, Logs, Session Replay, and so on each have individual modules, allowing you to integrate only what is needed into your application.

SDK v2 offers a unified API layout and naming alignment between the iOS SDK, the Android SDK, and other Datadog products.

SDK v2 enables the usage of [Mobile Session Replay](https://docs.datadoghq.com/session_replay/mobile/) on Android and iOS applications.
{% /tab %}

{% tab title="React Native" %}
The migration from v1 to v2 comes with improved performance.
{% /tab %}

{% tab title="Flutter" %}
The migration from v1 to v2 comes with improved performance and additional features supplied by the v2 Native SDKs.
{% /tab %}

### Modules{% #modules-1 %}

{% tab title="Android" %}
Artifacts are modularized in v2. Adopt the following artifacts:

- RUM: `com.datadoghq:dd-sdk-android-rum:x.x.x`
- Logs: `com.datadoghq:dd-sdk-android-logs:x.x.x`
- Trace: `com.datadoghq:dd-sdk-android-trace:x.x.x`
- Session Replay: `com.datadoghq:dd-sdk-android-session-replay:x.x.x`
- WebView Tracking: `com.datadoghq:dd-sdk-android-webview:x.x.x`
- OkHttp instrumentation: `com.datadoghq:dd-sdk-android-okhttp:x.x.x`

**Note**: If you use NDK Crash Reporting and WebView Tracking, you must add RUM and Logs artifacts to report events to RUM and Logs respectively.

Reference to the `com.datadoghq:dd-sdk-android` artifact should be removed from your Gradle build script, as this artifact doesn't exist anymore.

**Note**: The Maven coordinates of all the other artifacts stay the same.

{% alert level="danger" %}
v2 does not support Android API 19 (KitKat). The minimum SDK supported is now API 21 (Lollipop). Kotlin 1.7 is required. The SDK itself is compiled with Kotlin 1.8, so a compiler of Kotlin 1.6 and below cannot read SDK classes metadata.
{% /alert %}

Should you encounter an error such as the following:

```
A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and kotlin-stdlib-jdk8-1.7.20 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20)
```

Add the following rules to your build script (more details in the relevant [Stack Overflow issue](https://stackoverflow.com/a/75298544)):

```kotlin
dependencies {
    constraints {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.10") {
            because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib")
        }
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.10") {
            because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib")
        }
    }
}
```

See the [Android sample application](https://github.com/DataDog/dd-sdk-android/tree/develop/sample) for an example of how to set up the SDK.
{% /tab %}

{% tab title="iOS" %}
Libraries are modularized in v2. Adopt the following libraries:

- `DatadogCore`
- `DatadogLogs`
- `DatadogTrace`
- `DatadogSessionReplay`
- `DatadogRUM`
- `DatadogWebViewTracking`

These come in addition to the existing `DatadogCrashReporting` and `DatadogObjc`.

{% collapsible-section %}
## SPM (Recommended)

```swift
let package = Package(
  ...
  dependencies: [
      .package(url: "https://github.com/DataDog/dd-sdk-ios", from: "2.0.0")
  ],
  targets: [
      .target(
          ...
          dependencies: [
              .product(name: "DatadogCore", package: "dd-sdk-ios"),
              .product(name: "DatadogLogs", package: "dd-sdk-ios"),
              .product(name: "DatadogTrace", package: "dd-sdk-ios"),
              .product(name: "DatadogSessionReplay", package: "dd-sdk-ios"),
              .product(name: "DatadogRUM", package: "dd-sdk-ios"),
              .product(name: "DatadogCrashReporting", package: "dd-sdk-ios"),
              .product(name: "DatadogWebViewTracking", package: "dd-sdk-ios"),
          ]
      ),
  ]
)
```

{% /collapsible-section %}

{% collapsible-section %}
## CocoaPods

```ruby
pod 'DatadogCore'
pod 'DatadogLogs'
pod 'DatadogTrace'
pod 'DatadogSessionReplay'
pod 'DatadogRUM'
pod 'DatadogCrashReporting'
pod 'DatadogWebViewTracking'
pod 'DatadogObjc'
```

{% /collapsible-section %}

{% collapsible-section %}
## Carthage

The `Cartfile` stays the same:

```
github "DataDog/dd-sdk-ios"
```

In Xcode, you **must** link the following frameworks:

```
DatadogInternal.xcframework
DatadogCore.xcframework
```

Then, you can select the modules you want to use:

```
DatadogLogs.xcframework
DatadogTrace.xcframework
DatadogSessionReplay.xcframework
DatadogRUM.xcframework
DatadogCrashReporting.xcframework + CrashReporter.xcframework
DatadogWebViewTracking.xcframework
DatadogObjc.xcframework
```

{% /collapsible-section %}

**Note**: When using Crash Reporting and WebView Tracking, you must add the RUM and Logs modules to report events to RUM and Logs respectively.
{% /tab %}

{% tab title="React Native" %}
Update `@datadog/mobile-react-native` in your package.json:

```json
"@datadog/mobile-react-native": "2.0.0"
```

Update your iOS pods:

```bash
(cd ios && bundle exec pod update)
```

If you use a React Native version strictly over `0.67`, use Java version 17. If you use React Native version equal or below ot `0.67`, use Java version 11. To check your Java version, run the following in a terminal:

```bash
java --version
```

### For React Native < 0.73{% #for-react-native--073 %}

In your `android/build.gradle` file, specify the `kotlinVersion` to avoid clashes among Kotlin dependencies:

```groovy
buildscript {
    ext {
        // targetSdkVersion = ...
        kotlinVersion = "1.8.21"
    }
}
```

### For React Native < 0.68{% #for-react-native--068 %}

In your `android/build.gradle` file, specify the `kotlinVersion` to avoid clashes among Kotlin dependencies:

```groovy
buildscript {
    ext {
        // targetSdkVersion = ...
        kotlinVersion = "1.8.21"
    }
}
```

If you are using a version of `com.android.tools.build:gradle` below `5.0` in your `android/build.gradle`, add in your `android/gradle.properties` file:

```properties
android.jetifier.ignorelist=dd-sdk-android-core
```

### Troubleshooting{% #troubleshooting %}

#### Android build fails with `Unable to make field private final java.lang.String java.io.File.path accessible`{% #android-build-fails-with-unable-to-make-field-private-final-javalangstring-javaiofilepath-accessible %}

If your Android build fails with an error like:

```
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:processReleaseMainManifest'.
> Unable to make field private final java.lang.String java.io.File.path accessible: module java.base does not "opens java.io" to unnamed module @1bbf7f0e
```

You are using Java 17, which is not compatible with your React Native version. Switch to Java 11 to solve the issue.

#### Android build fails with `Unsupported class file major version 61`{% #android-build-fails-with-unsupported-class-file-major-version-61 %}

If your Android build fails with an error like:

```
FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':app:lintVitalRelease'.
> Could not resolve all artifacts for configuration ':app:debugRuntimeClasspath'.
   > Failed to transform dd-sdk-android-core-2.0.0.aar (com.datadoghq:dd-sdk-android-core:2.0.0) to match attributes {artifactType=android-manifest, org.gradle.category=library, org.gradle.dependency.bundling=external, org.gradle.libraryelements=aar, org.gradle.status=release, org.gradle.usage=java-runtime}.
      > Execution failed for JetifyTransform: /Users/me/.gradle/caches/modules-2/files-2.1/com.datadoghq/dd-sdk-android-core/2.0.0/a97f8a1537da1de99a86adf32c307198b477971f/dd-sdk-android-core-2.0.0.aar.
         > Failed to transform '/Users/me/.gradle/caches/modules-2/files-2.1/com.datadoghq/dd-sdk-android-core/2.0.0/a97f8a1537da1de99a86adf32c307198b477971f/dd-sdk-android-core-2.0.0.aar' using Jetifier. Reason: IllegalArgumentException, message: Unsupported class file major version 61. (Run with --stacktrace for more details.)
```

You use a version of Android Gradle Plugin below `5.0`. To fix the issue, add in your `android/gradle.properties` file:

```properties
android.jetifier.ignorelist=dd-sdk-android-core
```

#### Android build fails with `Duplicate class kotlin.collections.jdk8.*`{% #android-build-fails-with-duplicate-class-kotlincollectionsjdk8 %}

If your Android build fails with an error like:

```
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:checkReleaseDuplicateClasses'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
   > Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.7.20 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20)
     Duplicate class kotlin.internal.jdk7.JDK7PlatformImplementations found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk7-1.7.20 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.20)
```

You need to set a Kotlin version for your project to avoid clashes among Kotlin dependencies. In your `android/build.gradle` file, specify the `kotlinVersion`:

```groovy
buildscript {
    ext {
        // targetSdkVersion = ...
        kotlinVersion = "1.8.21"
    }
}
```

Alternatively, you can add the following rules to your build script in your `android/app/build.gradle` file:

```groovy
dependencies {
    constraints {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.10") {
            because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib")
        }
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.10") {
            because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib")
        }
    }
}
```

{% /tab %}

{% tab title="Flutter" %}
Update `datadog_flutter_plugin` in your pubspec.yaml:

```yaml
dependencies:
  'datadog_flutter_plugin: ^2.0.0
```

## Troubleshooting{% #troubleshooting %}

### Duplicate interface (iOS){% #duplicate-interface-ios %}

If you see this error while building iOS after upgrading to `datadog_flutter_plugin` v2.0:

```zed
Semantic Issue (Xcode): Duplicate interface definition for class 'DatadogSdkPlugin'
/Users/exampleuser/Projects/test_app/build/ios/Debug-iphonesimulator/datadog_flutter_plugin/datadog_flutter_plugin.framework/Headers/DatadogSdkPlugin.h:6:0
```

Try performing `flutter clean && flutter pub get` and rebuilding. This usually resolves the issue.

### Duplicate classes (Android){% #duplicate-classes-android %}

If you see this error while building Android after the upgrading to `datadog_flutter_plugin` v2.0:

```
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:checkDebugDuplicateClasses'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
```

Make sure that you've updated your version of Kotlin to at least 1.8 in your `build.gradle` file.
{% /tab %}

### SDK initialization{% #sdk-initialization %}

{% tab title="Android" %}
With the extraction of different products into independent modules, the SDK configuration is organized by module.

`com.datadog.android.core.configuration.Configuration.Builder` class has the following changes:

- Client token, env name, variant name (default value is empty string), and service name (default value is application ID taken from the manifest) should be provided in the constructor.
- The `com.datadog.android.core.configuration.Credentials` class is removed.
- `logsEnabled`, `tracesEnabled`, and `rumEnabled` are removed from the constructor in favour of individual product configuration (see below).
- `crashReportsEnabled` constructor argument is removed. You can enable or disable JVM crash reporting with the `Configuration.Builder.setCrashReportsEnabled` method. By default, JVM crash reporting is enabled.
- RUM, Logs, and Trace product configuration methods are removed from `Configuration.Builder` in favor of the individual product configuration (see below).

The `Datadog.initialize` method has the `Credentials` class removed from the list of the arguments.

The `com.datadog.android.plugin` package and all related classes/methods are removed.

### Logs{% #logs %}

All the classes related to the Logs product are strictly contained in the `com.datadog.android.log` package.

To use Logs product, import the following artifact:

```kotlin
implementation("com.datadoghq:dd-sdk-android-logs:x.x.x")
```

You can enable the Logs product with the following snippet:

```kotlin
val logsConfig = LogsConfiguration.Builder()
    ...
    .build()

Logs.enable(logsConfig)

val logger = Logger.Builder()
    ...
    .build()
```

API changes:

| `1.x`                                                                                | `2.0`                                                                                                                                          |
| ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `com.datadog.android.core.configuration.Configuration.Builder.setLogEventMapper`     | `com.datadog.android.log.LogsConfiguration.Builder.setEventMapper`                                                                             |
| `com.datadog.android.core.configuration.Configuration.Builder.useCustomLogsEndpoint` | `com.datadog.android.log.LogsConfiguration.Builder.useCustomEndpoint`                                                                          |
| `com.datadog.android.log.Logger.Builder.setLoggerName`                               | `com.datadog.android.log.Logger.Builder.setName`                                                                                               |
| `com.datadog.android.log.Logger.Builder.setSampleRate`                               | `com.datadog.android.log.Logger.Builder.setRemoteSampleRate`                                                                                   |
| `com.datadog.android.log.Logger.Builder.setDatadogLogsEnabled`                       | This method has been removed. Use `com.datadog.android.log.Logger.Builder.setRemoteSampleRate(0f)` instead to disable sending logs to Datadog. |
| `com.datadog.android.log.Logger.Builder.setServiceName`                              | `com.datadog.android.log.Logger.Builder.setService`                                                                                            |
| `com.datadog.android.log.Logger.Builder.setDatadogLogsMinPriority`                   | `com.datadog.android.log.Logger.Builder.setRemoteLogThreshold`                                                                                 |

### Trace{% #trace %}

All the classes related to the Trace product are strictly contained in the `com.datadog.android.trace` package (this means that all classes residing in `com.datadog.android.tracing` before have moved).

To use the Trace product, import the following artifact:

```kotlin
implementation("com.datadoghq:dd-sdk-android-trace:x.x.x")
```

You can enable the Trace product with the following snippet:

```kotlin
val traceConfig = TraceConfiguration.Builder()
    ...
    .build()

Trace.enable(traceConfig)

val tracer = AndroidTracer.Builder()
    ...
    .build()

GlobalTracer.registerIfAbsent(tracer)
```

API changes:

| `1.x`                                                                                  | `2.0`                                                                    |
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| `com.datadog.android.core.configuration.Configuration.Builder.setSpanEventMapper`      | `com.datadog.android.trace.TraceConfiguration.Builder.setEventMapper`    |
| `com.datadog.android.core.configuration.Configuration.Builder.useCustomTracesEndpoint` | `com.datadog.android.trace.TraceConfiguration.Builder.useCustomEndpoint` |
| `com.datadog.android.tracing.AndroidTracer.Builder.setSamplingRate`                    | `com.datadog.android.trace.AndroidTracer.Builder.setSampleRate`          |
| `com.datadog.android.tracing.AndroidTracer.Builder.setServiceName`                     | `com.datadog.android.trace.AndroidTracer.Builder.setService`             |

### RUM{% #rum %}

All classes related to the RUM product are strictly contained in the `com.datadog.android.rum` package.

To use the RUM product, import the following artifact:

```kotlin
implementation("com.datadoghq:dd-sdk-android-rum:x.x.x")
```

You can enable the RUM product with the following snippet:

```kotlin
val rumConfig = RumConfiguration.Builder(rumApplicationId)
    ...
    .build()

Rum.enable(rumConfig)
```

API changes:

| `1.x`                                                                                     | `2.0`                                                                                                 |
| ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `com.datadog.android.core.configuration.Configuration.Builder.setRumViewEventMapper`      | `com.datadog.android.rum.RumConfiguration.Builder.setViewEventMapper`                                 |
| `com.datadog.android.core.configuration.Configuration.Builder.setRumResourceEventMapper`  | `com.datadog.android.rum.RumConfiguration.Builder.setResourceEventMapper`                             |
| `com.datadog.android.core.configuration.Configuration.Builder.setRumActionEventMapper`    | `com.datadog.android.rum.RumConfiguration.Builder.setActionEventMapper`                               |
| `com.datadog.android.core.configuration.Configuration.Builder.setRumErrorEventMapper`     | `com.datadog.android.rum.RumConfiguration.Builder.setErrorEventMapper`                                |
| `com.datadog.android.core.configuration.Configuration.Builder.setRumLongTaskEventMapper`  | `com.datadog.android.rum.RumConfiguration.Builder.setLongTaskEventMapper`                             |
| `com.datadog.android.core.configuration.Configuration.Builder.useCustomRumEndpoint`       | `com.datadog.android.rum.RumConfiguration.Builder.useCustomEndpoint`                                  |
| `com.datadog.android.event.ViewEventMapper`                                               | `com.datadog.android.rum.event.ViewEventMapper`                                                       |
| `com.datadog.android.core.configuration.VitalsUpdateFrequency`                            | `com.datadog.android.rum.configuration.VitalsUpdateFrequency`                                         |
| `com.datadog.android.core.configuration.Configuration.Builder.trackInteractions`          | `com.datadog.android.rum.RumConfiguration.Builder.trackUserInteractions`                              |
| `com.datadog.android.core.configuration.Configuration.Builder.disableInteractionTracking` | `com.datadog.android.rum.RumConfiguration.Builder.disableUserInteractionTracking`                     |
| `com.datadog.android.core.configuration.Configuration.Builder.sampleRumSessions`          | `com.datadog.android.rum.RumConfiguration.Builder.setSessionSampleRate`                               |
| `com.datadog.android.core.configuration.Configuration.Builder.sampleTelemetry`            | `com.datadog.android.rum.RumConfiguration.Builder.setTelemetrySampleRate`                             |
| `com.datadog.android.rum.RumMonitor.Builder`                                              | This class has been removed. The RUM monitor is created and registered during the `Rum.enable` call.  |
| `com.datadog.android.rum.RumMonitor.Builder.sampleRumSessions`                            | `com.datadog.android.rum.RumConfiguration.Builder.setSessionSampleRate`                               |
| `com.datadog.android.rum.RumMonitor.Builder.setSessionListener`                           | `com.datadog.android.rum.RumConfiguration.Builder.setSessionListener`                                 |
| `com.datadog.android.rum.RumMonitor.addUserAction`                                        | `com.datadog.android.rum.RumMonitor.addAction`                                                        |
| `com.datadog.android.rum.RumMonitor.startUserAction`                                      | `com.datadog.android.rum.RumMonitor.startAction`                                                      |
| `com.datadog.android.rum.RumMonitor.stopUserAction`                                       | `com.datadog.android.rum.RumMonitor.stopAction`                                                       |
| `com.datadog.android.rum.GlobalRum.registerIfAbsent`                                      | This method has been removed. The RUM monitor is created and registered during the `Rum.enable` call. |
| `com.datadog.android.rum.GlobalRum`                                                       | `com.datadog.android.rum.GlobalRumMonitor`                                                            |
| `com.datadog.android.rum.GlobalRum.addAttribute`                                          | `com.datadog.android.rum.RumMonitor.addAttribute`                                                     |
| `com.datadog.android.rum.GlobalRum.removeAttribute`                                       | `com.datadog.android.rum.RumMonitor.removeAttribute`                                                  |

### NDK Crash Reporting{% #ndk-crash-reporting %}

The artifact name stays the same as before: `com.datadoghq:dd-sdk-android-ndk:x.x.x`.

You can enable NDK Crash Reporting with the following snippet:

```kotlin
NdkCrashReports.enable()
```

This configuration replaces the `com.datadog.android.core.configuration.Configuration.Builder.addPlugin` call.

**Note**: You should have RUM and Logs products enabled to receive NDK crash reports in RUM and Logs respectively.

### WebView Tracking{% #webview-tracking %}

The artifact name stays the same as before: `com.datadoghq:dd-sdk-android-webview:x.x.x`

You can enable WebView Tracking with the following snippet:

```kotlin
WebViewTracking.enable(webView, allowedHosts)
```

**Note**: You should have RUM and Logs products enabled to receive events coming from WebView in RUM and Logs respectively.

API changes:

| `1.x`                                                | `2.0`                                                                  |
| ---------------------------------------------------- | ---------------------------------------------------------------------- |
| `com.datadog.android.webview.DatadogEventBridge`     | This method became an `internal` class. Use `WebViewTracking` instead. |
| `com.datadog.android.rum.webview.RumWebChromeClient` | This class was removed. Use `WebViewTracking` instead.                 |
| `com.datadog.android.rum.webview.RumWebViewClient`   | This class was removed. Use `WebViewTracking` instead.                 |

### OkHttp Tracking{% #okhttp-tracking %}

To use OkHttp Tracking, import the following artifact:

```kotlin
implementation("com.datadoghq:dd-sdk-android-okhttp:x.x.x")
```

OkHttp instrumentation supports the initialization of the Datadog SDK after the OkHttp client, allowing you to create `com.datadog.android.okhttp.DatadogEventListener`, `com.datadog.android.okhttp.DatadogInterceptor`, and `com.datadog.android.okhttp.trace.TracingInterceptor` before the Datadog SDK. OkHttp instrumentation starts reporting events to Datadog once the Datadog SDK is initialized.

Both `com.datadog.android.okhttp.DatadogInterceptor` and `com.datadog.android.okhttp.trace.TracingInterceptor` allow you to control sampling dynamically through integration with a remote configuration system.

To dynamically adjust sampling, provide your own implementation of the `com.datadog.android.core.sampling.Sampler` interface in the `com.datadog.android.okhttp.DatadogInterceptor`/`com.datadog.android.okhttp.trace.TracingInterceptor` constructor. It is queried for each request to make the sampling decision.

### `dd-sdk-android-ktx` module removal{% #dd-sdk-android-ktx-module-removal %}

To improve granularity for the Datadog SDK libraries used, the `dd-sdk-android-ktx` module is removed. The code is distributed between the other modules to provide extension methods for both RUM and Trace features.

| `1.x`                                                                                     | '2.0'                                                                                       | Module name                       |
| ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | --------------------------------- |
| `com.datadog.android.ktx.coroutine#kotlinx.coroutines.CoroutineScope.launchTraced`        | `com.datadog.android.trace.coroutines#kotlinx.coroutines.CoroutineScope.launchTraced`       | `dd-sdk-android-trace-coroutines` |
| `com.datadog.android.ktx.coroutine#runBlockingTraced`                                     | `com.datadog.android.trace.coroutines#runBlockingTraced`                                    | `dd-sdk-android-trace-coroutines` |
| `com.datadog.android.ktx.coroutine#kotlinx.coroutines.CoroutineScope.asyncTraced`         | `com.datadog.android.trace.coroutines#kotlinx.coroutines.CoroutineScope.asyncTraced`        | `dd-sdk-android-trace-coroutines` |
| `com.datadog.android.ktx.coroutine#kotlinx.coroutines.Deferred<T>.awaitTraced`            | `com.datadog.android.trace.coroutines#kotlinx.coroutines.Deferred<T>.awaitTraced`           | `dd-sdk-android-trace-coroutines` |
| `com.datadog.android.ktx.coroutine#withContextTraced`                                     | `com.datadog.android.trace.coroutines#withContextTraced`                                    | `dd-sdk-android-trace-coroutines` |
| `com.datadog.android.ktx.coroutine.CoroutineScopeSpan`                                    | `com.datadog.android.trace.coroutines.CoroutineScopeSpan`                                   | `dd-sdk-android-trace-coroutines` |
| `com.datadog.android.ktx.sqlite#android.database.sqlite.SQLiteDatabase.transactionTraced` | `com.datadog.android.trace.sqlite#android.database.sqlite.SQLiteDatabase.transactionTraced` | `dd-sdk-android-trace`            |
| `com.datadog.android.ktx.tracing#io.opentracing.Span.setError`                            | `com.datadog.android.trace#io.opentracing.Span.setError`                                    | `dd-sdk-android-trace`            |
| `com.datadog.android.ktx.tracing#withinSpan`                                              | `com.datadog.android.trace#withinSpan`                                                      | `dd-sdk-android-trace`            |
| `com.datadog.android.ktx.coroutine#sendErrorToDatadog`                                    | `com.datadog.android.rum.coroutines#sendErrorToDatadog`                                     | `dd-sdk-android-rum-coroutines`   |
| `com.datadog.android.ktx.rum#java.io.Closeable.useMonitored`                              | `com.datadog.android.rum#java.io.Closeable.useMonitored`                                    | `dd-sdk-android-rum`              |
| `com.datadog.android.ktx.rum#android.content.Context.getAssetAsRumResource`               | `com.datadog.android.rum.resource#android.content.Context.getAssetAsRumResource`            | `dd-sdk-android-rum`              |
| `com.datadog.android.ktx.rum#android.content.Context.getRawResAsRumResource`              | `com.datadog.android.rum.resource#android.content.Context.getRawResAsRumResource`           | `dd-sdk-android-rum`              |
| `com.datadog.android.ktx.rum#java.io.InputStream.asRumResource`                           | `com.datadog.android.rum.resource#java.io.InputStream.asRumResource`                        | `dd-sdk-android-rum`              |
| `com.datadog.android.ktx.tracing#okhttp3.Request.Builder.parentSpan`                      | `com.datadog.android.okhttp.trace#okhttp3.Request.Builder.parentSpan`                       | `dd-sdk-android-okhttp`           |

### Session Replay{% #session-replay %}

For instructions on setting up Mobile Session Replay, see [Mobile Session Replay Setup and Configuration](https://docs.datadoghq.com/session_replay/mobile/setup_and_configuration/?tab=android).
{% /tab %}

{% tab title="iOS" %}
With the extraction of different products into independent modules, the SDK configuration is organized by module.

The SDK must be initialized before enabling any product.

The Builder pattern of the SDK initialization has been removed in favor of structure definitions. The following example shows how a `1.x` initialization would translate in `2.0`.

**V1 Initialization**

```swift
import Datadog

Datadog.initialize(
    appContext: .init(),
    trackingConsent: .granted,
    configuration: Datadog.Configuration
        .builderUsing(
            clientToken: "<client token>",
            environment: "<environment>"
        )
        .set(serviceName: "<service name>")
        .build()
```

**V2 Initialization**

```swift
import DatadogCore

Datadog.initialize(
    with: Datadog.Configuration(
        clientToken: "<client token>",
        env: "<environment>",
        service: "<service name>"
    ),
    trackingConsent: .granted
)
```

API changes:

| `1.x`                                                    | `2.0`                                      |
| -------------------------------------------------------- | ------------------------------------------ |
| `Datadog.Configuration.Builder.set(serviceName:)`        | `Datadog.Configuration.service`            |
| `Datadog.Configuration.Builder.set(batchSize:)`          | `Datadog.Configuration.batchSize`          |
| `Datadog.Configuration.Builder.set(uploadFrequency:)`    | `Datadog.Configuration.uploadFrequency`    |
| `Datadog.Configuration.Builder.set(proxyConfiguration:)` | `Datadog.Configuration.proxyConfiguration` |
| `Datadog.Configuration.Builder.set(encryption:)`         | `Datadog.Configuration.encryption`         |
| `Datadog.Configuration.Builder.set(serverDateProvider:)` | `Datadog.Configuration.serverDateProvider` |
| `Datadog.AppContext(mainBundle:)`                        | `Datadog.Configuration.bundle`             |

### Logs{% #logs %}

All the classes related to Logs are strictly in the `DatadogLogs` module. You first need to enable the product:

```swift
import DatadogLogs

Logs.enable(with: Logs.Configuration(...))
```

Then, you can create a logger instance:

```swift
import DatadogLogs

let logger = Logger.create(
    with: Logger.Configuration(name: "<logger name>")
)
```

API changes:

| `1.x`                                                     | `2.0`                                         |
| --------------------------------------------------------- | --------------------------------------------- |
| `Datadog.Configuration.Builder.setLogEventMapper(_:)`     | `Logs.Configuration.eventMapper`              |
| `Datadog.Configuration.Builder.set(loggingSamplingRate:)` | `Logs.Configuration.eventMapper`              |
| `Logger.Builder.set(serviceName:)`                        | `Logger.Configuration.service`                |
| `Logger.Builder.set(loggerName:)`                         | `Logger.Configuration.name`                   |
| `Logger.Builder.sendNetworkInfo(_:)`                      | `Logger.Configuration.networkInfoEnabled`     |
| `Logger.Builder.bundleWithRUM(_:)`                        | `Logger.Configuration.bundleWithRumEnabled`   |
| `Logger.Builder.bundleWithTrace(_:)`                      | `Logger.Configuration.bundleWithTraceEnabled` |
| `Logger.Builder.sendLogsToDatadog(false)`                 | `Logger.Configuration.remoteSampleRate = 0`   |
| `Logger.Builder.set(datadogReportingThreshold:)`          | `Logger.Configuration.remoteLogThreshold`     |
| `Logger.Builder.printLogsToConsole(_:, usingFormat)`      | `Logger.Configuration.consoleLogFormat`       |

### Trace{% #trace %}

All the classes related to Trace are strictly in the `DatadogTrace` module. You first need to enable the product:

```swift
import DatadogTrace

Trace.enable(
    with: Trace.Configuration(...)
)
```

Then, you can access the shared Tracer instance:

```swift
import DatadogTrace

let tracer = Tracer.shared()
```

API changes:

| `1.x`                                                     | `2.0`                                      |
| --------------------------------------------------------- | ------------------------------------------ |
| `Datadog.Configuration.Builder.trackURLSession(_:)`       | `Trace.Configuration.urlSessionTracking`   |
| `Datadog.Configuration.Builder.setSpanEventMapper(_:)`    | `Trace.Configuration.eventMapper`          |
| `Datadog.Configuration.Builder.set(tracingSamplingRate:)` | `Trace.Configuration.sampleRate`           |
| `Tracer.Configuration.serviceName`                        | `Trace.Configuration.service`              |
| `Tracer.Configuration.sendNetworkInfo`                    | `Trace.Configuration.networkInfoEnabled`   |
| `Tracer.Configuration.globalTags`                         | `Trace.Configuration.tags`                 |
| `Tracer.Configuration.bundleWithRUM`                      | `Trace.Configuration.bundleWithRumEnabled` |
| `Tracer.Configuration.samplingRate`                       | `Trace.Configuration.sampleRate`           |

### RUM{% #rum %}

All the classes related to RUM are strictly in the `DatadogRUM` module. You first need to enable the product:

```swift
import DatadogRUM

RUM.enable(
    with: RUM.Configuration(applicationID: "<RUM Application ID>")
)
```

Then, you can access the shared RUM monitor instance:

```swift
import DatadogRUM

let monitor = RUMMonitor.shared()
```

API changes:

| `1.x`                                                                | `2.0`                                                             |
| -------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `Datadog.Configuration.Builder.trackURLSession(_:)`                  | `RUM.Configuration.urlSessionTracking`                            |
| `Datadog.Configuration.Builder.set(rumSessionsSamplingRate:)`        | `RUM.Configuration.sessionSampleRate`                             |
| `Datadog.Configuration.Builder.onRUMSessionStart`                    | `RUM.Configuration.onSessionStart`                                |
| `Datadog.Configuration.Builder.trackUIKitRUMViews(using:)`           | `RUM.Configuration.uiKitViewsPredicate`                           |
| `Datadog.Configuration.Builder.trackUIKitRUMActions(using:)`         | `RUM.Configuration.uiKitActionsPredicate`                         |
| `Datadog.Configuration.Builder.trackRUMLongTasks(threshold:)`        | `RUM.Configuration.longTaskThreshold`                             |
| `Datadog.Configuration.Builder.setRUMViewEventMapper(_:)`            | `RUM.Configuration.viewEventMapper`                               |
| `Datadog.Configuration.Builder.setRUMResourceEventMapper(_:)`        | `RUM.Configuration.resourceEventMapper`                           |
| `Datadog.Configuration.Builder.setRUMActionEventMapper(_:)`          | `RUM.Configuration.actionEventMapper`                             |
| `Datadog.Configuration.Builder.setRUMErrorEventMapper(_:)`           | `RUM.Configuration.errorEventMapper`                              |
| `Datadog.Configuration.Builder.setRUMLongTaskEventMapper(_:)`        | `RUM.Configuration.longTaskEventMapper`                           |
| `Datadog.Configuration.Builder.setRUMResourceAttributesProvider(_:)` | `RUM.Configuration.urlSessionTracking.resourceAttributesProvider` |
| `Datadog.Configuration.Builder.trackBackgroundEvents(_:)`            | `RUM.Configuration.trackBackgroundEvents`                         |
| `Datadog.Configuration.Builder.trackFrustrations(_:)`                | `RUM.Configuration.frustrationsTracking`                          |
| `Datadog.Configuration.Builder.set(mobileVitalsFrequency:)`          | `RUM.Configuration.vitalsUpdateFrequency`                         |
| `Datadog.Configuration.Builder.set(sampleTelemetry:)`                | `RUM.Configuration.telemetrySampleRate`                           |

### Crash Reporting{% #crash-reporting %}

To enable Crash Reporting, make sure to enable RUM and Logs to report to those products respectively.

```swift
import DatadogCrashReporting

CrashReporting.enable()
```

| `1.x`                                                  | `2.0`                     |
| ------------------------------------------------------ | ------------------------- |
| `Datadog.Configuration.Builder.enableCrashReporting()` | `CrashReporting.enable()` |

### WebView Tracking{% #webview-tracking %}

To enable WebViewTracking, make sure to also enable RUM and Logs to report to those products respectively.

```swift
import WebKit
import DatadogWebViewTracking

let webView = WKWebView(...)
WebViewTracking.enable(webView: webView)
```

| `1.x`                                                | `2.0`                              |
| ---------------------------------------------------- | ---------------------------------- |
| `WKUserContentController.startTrackingDatadogEvents` | `WebViewTracking.enable(webView:)` |

### Session Replay{% #session-replay %}

For instructions on setting up Mobile Session Replay, see [Mobile Session Replay Setup and Configuration](https://docs.datadoghq.com/session_replay/mobile/setup_and_configuration/?tab=ios).
{% /tab %}

{% tab title="React Native" %}
No change in the SDK initialization is needed.
{% /tab %}

{% tab title="Flutter" %}
## SDK Configuration Changes{% #sdk-configuration-changes %}

Certain configuration properties have been moved or renamed to support modularity in Datadog's native SDKs.

The following structures have been renamed:

| `1.x`                        | `2.x`                         |
| ---------------------------- | ----------------------------- |
| `DdSdkConfiguration`         | `DatadogConfiguration`        |
| `LoggingConfiguration`       | `DatadogLoggingConfiguration` |
| `RumConfiguration`           | `DatadogRumConfiguration`     |
| `DdSdkExistingConfiguration` | `DatadogAttachConfiguration`  |

The following properties have changed:

| 1.x                                      | 2.x                                           | Notes                        |
| ---------------------------------------- | --------------------------------------------- | ---------------------------- |
| `DdSdkConfiguration.trackingConsent`     | Removed                                       | Part of `Datadog.initialize` |
| `DdSdkConfiguration.customEndpoint`      | Removed                                       | Now configured per-feature   |
| `DdSdkConfiguration.serviceName`         | `DatadogConfiguration.service`                |
| `DdSdkConfiguration.logEventMapper`      | `DatadogLoggingConfiguration.eventMapper`     |
| `DdSdkConfiguration.customLogsEndpoint`  | `DatadogLoggingConfiguration.customEndpoint`  |
| `DdSdkConfiguration.telemetrySampleRate` | `DatadogRumConfiguration.telemetrySampleRate` |

In addition, the following APIs have changed:

| 1.x                                 | 2.x                                       | Notes                               |
| ----------------------------------- | ----------------------------------------- | ----------------------------------- |
| `Verbosity`                         | Removed                                   | See `CoreLoggerLevel` or `LogLevel` |
| `DdLogs DatadogSdk.logs`            | `DatadogLogging DatadogSdk.logs`          | Type changed                        |
| `DdRum DatadogSdk.rum`              | `DatadogRum DatadogSdk.rum`               | Type changed                        |
| `Verbosity DatadogSdk.sdkVerbosity` | `CoreLoggerLevel DatadogSdk.sdkVerbosity` |
| `DatadogSdk.runApp`                 | `DatadogSdk.runApp`                       | Added `trackingConsent` parameter   |
| `DatadogSdk.initialize`             | `DatadogSdk.initialize`                   | Added `trackingConsent` parameter   |
| `DatadogSdk.createLogger`           | `DatadogLogging.createLogger`             | Moved                               |

## Flutter Web Changes{% #flutter-web-changes %}

Clients using Flutter Web should update to using the Datadog Browser SDK v5. Change the following import in your `index.html`:

```diff
-  <script type="text/javascript" src="https://www.datadoghq-browser-agent.com/datadog-logs-v4.js"></script>
-  <script type="text/javascript" src="https://www.datadoghq-browser-agent.com/datadog-rum-slim-v4.js"></script>
+  <script type="text/javascript" src="https://www.datadoghq-browser-agent.com/us1/v5/datadog-logs.js"></script>
+  <script type="text/javascript" src="https://www.datadoghq-browser-agent.com/us1/v5/datadog-rum-slim.js"></script>
```

**Note**: Datadog provides one CDN bundle per site. See the [Browser SDK README](https://github.com/DataDog/browser-sdk/#cdn-bundles) for a list of all site URLs.

## Logs product changes{% #logs-product-changes %}

As with v1, Datadog Logging can be enabled by setting the `DatadogConfiguration.loggingConfiguration` member. However, unlike v1, Datadog does not create a default logger for you. `DatadogSdk.logs` is now an instance of `DatadogLogging`, which can be used to create logs. Many options were moved to `DatadogLoggerConfiguration` to give developers more granular support over individual loggers.

The following APIs have changed:

| 1.x                                              | 2.x                                                   | Notes                                                        |
| ------------------------------------------------ | ----------------------------------------------------- | ------------------------------------------------------------ |
| `LoggingConfiguration`                           | `DatadogLoggingConfiguration`                         | Renamed most members are now on `DatadogLoggerConfiguration` |
| `LoggingConfiguration.sendNetworkInfo`           | `DatadogLoggerConfiguration.networkInfoEnabled`       |
| `LoggingConfiguration.printLogsToConsole`        | `DatadogLoggerConfiguration.customConsoleLogFunction` |
| `LoggingConfiguration.sendLogsToDatadog`         | Removed. Use `remoteLogThreshold` instead             |
| `LoggingConfiguration.datadogReportingThreshold` | `DatadogLoggerConfiguration.remoteLogThreshold`       |
| `LoggingConfiguration.bundleWithRum`             | `DatadogLoggerConfiguration.bundleWithRumEnabled`     |
| `LoggingConfiguration.bundleWithTrace`           | `DatadogLoggerConfiguration.bundleWithTraceEnabled`   |
| `LoggingConfiguration.loggerName`                | `DatadogLoggerConfiguration.name`                     |
| `LoggingConfiguration.sampleRate`                | `DatadogLoggerConfiguration.remoteSampleRate`         |

## RUM Product Changes{% #rum-product-changes %}

The following APIs have changed:

| 1.x                                       | 2.x                                             | Notes                                   |
| ----------------------------------------- | ----------------------------------------------- | --------------------------------------- |
| `RumConfiguration`                        | `DatadogRumConfiguration`                       | Type renamed                            |
| `RumConfiguration.vitalsUpdateFrequency`  | `DatadogRumConfiguration.vitalsUpdateFrequency` | Set to `null` to disable vitals updates |
| `RumConfiguration.tracingSampleRate`      | `DatadogRumConfiguration.traceSampleRate`       |
| `RumConfiguration.rumViewEventMapper`     | `DatadogRumConfiguration.viewEventMapper`       |
| `RumConfiguration.rumActionEventMapper`   | `DatadogRumConfiguration.actionEventMapper`     |
| `RumConfiguration.rumResourceEventMapper` | `DatadogRumConfiguration.resourceEventMapper`   |
| `RumConfiguration.rumErrorEventMapper`    | `DatadogRumConfiguration.rumErrorEventMapper`   |
| `RumConfiguration.rumLongTaskEventMapper` | `DatadogRumConfiguration.longTaskEventMapper`   |
| `RumUserActionType`                       | `RumActionType`                                 | Type renamed                            |
| `DdRum.addUserAction`                     | `DdRum.addAction`                               |
| `DdRum.startUserAction`                   | `DdRum.startAction`                             |
| `DdRum.stopUserAction`                    | `DdRum.stopAction`                              |
| `DdRum.startResourceLoading`              | `DdRum.startResource`                           |
| `DdRum.stopResourceLoading`               | `DdRum.stopResource`                            |
| `DdRum.stopResourceLoadingWithError`      | `DdRum.stopResourceWithError`                   |

Additionally, event mappers no longer allow you to modify their view names. To rename a view, use a custom [`ViewInfoExtractor`](https://pub.dev/documentation/datadog_flutter_plugin/latest/datadog_flutter_plugin/ViewInfoExtractor.html) instead.
{% /tab %}

## Further Reading{% #further-reading %}

- [Visualize your RUM data in the Explorer](https://docs.datadoghq.com/real_user_monitoring/explorer)
- [Deprecation Policy for Datadog Mobile SDKs](https://docs.datadoghq.com/real_user_monitoring/guide/mobile-sdk-deprecation-policy)
