---
title: "iOS"
description: "Configure Middleware RUM for iOS apps to capture user sessions and frontend metrics efficiently."
section: "RUM"
breadcrumb: "RUM > Mobile > iOS"
canonical: "https://docs.middleware.io/get-started/rum/ios"
---
# iOS

The Middleware iOS RUM SDK collects user activity, application performance data, and errors from iOS applications. It helps you investigate crashes, slow screens, and failed requests in the context of a user session.

Collected data includes crashes, slow or frozen frames, network requests, and sessions. Session Replay adds visual context; correlation with backend traces helps follow a request beyond the mobile application when backend instrumentation is configured.

## Prerequisites

Before installing the SDK, make sure you have:

- iOS 13 or later.
- Xcode with Swift Package Manager support.
- A Middleware account and RUM application credentials.
- Access to your iOS application source code.
- HTTPS connectivity to your Middleware ingestion endpoint.

The SDK also supports macOS 10.15+ and tvOS 13+.

To check available SDKs in Xcode, run:

```shell
xcodebuild -showsdks
```

## Installation

#### 1 Create a RUM application

1. Log in to Middleware.
2. Go to **Installation → RUM**.
3. Select **iOS** as the platform.
4. Click **New Application**.
5. Enter your application name and click **Create Application**.
6. Copy the generated RUM access token and target URL.

#### 2 Install the iOS SDK

You can install the Middleware iOS SDK using Swift Package Manager or CocoaPods.

#### Swift Package Manager (recommended)

In Xcode:

1. Open your iOS project.
2. Go to **File → Add Package Dependencies**.
3. Enter the repository URL: `https://github.com/middleware-labs/middleware-ios`
4. Select version `2.3.2` or a compatible newer version.
5. Add the package to your application target.

For projects using `Package.swift`, add:

```swift
.package(
    url: "https://github.com/middleware-labs/middleware-ios",
    from: "2.3.2"
)
```

#### CocoaPods

Add the Middleware specs repo and the CocoaPods CDN to the top of your Podfile:

```ruby
source 'https://github.com/middleware-labs/cocoapods-specs.git'
source 'https://cdn.cocoapods.org/'
```

Keep both sources: new `MiddlewareRum` versions are published to the Middleware repo, and the SDK's dependencies still come from the CocoaPods CDN. CocoaPods trunk stops accepting new pods on December 2, 2026, so without the Middleware source your app stays on the last version published to trunk.

Add the following dependency to your Podfile:

```ruby
pod 'MiddlewareRum', '~> 2.3'
```

Install the dependency:

```bash
pod install
```

**Note**: `MiddlewareRum` is a static framework. If your project uses `use_frameworks!`, ensure dependent pods are linked statically.

#### 3 Initialize Middleware

Initialize the SDK as early as possible in your application's lifecycle to capture initial screens and application activity.

Choose the setup based on your application architecture.

#### SwiftUI

For SwiftUI applications, initialize Middleware in your application's `App` initializer.

```swift
import SwiftUI
import MiddlewareRum

@main
struct MyApp: App {

    init() {
        do {
            try MiddlewareRumBuilder()
                .target("https://<MW_UID>.middleware.io")
                .rumAccessToken("<MW_RUM_ACCESS_TOKEN>")
                .serviceName("my-ios-app")
                .projectName("My-iOS-App")
                .deploymentEnvironment("PROD")
                .globalAttributes([
                    "app.version": "1.0.0"
                ])
                .build()
        } catch {
            print("Middleware RUM initialization failed: \(error)")
        }
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
```

#### UIKit

For UIKit applications, initialize Middleware inside `AppDelegate`.

```swift
import UIKit
import MiddlewareRum

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions:
            [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {

        do {
            try MiddlewareRumBuilder()
                .target("https://<MW_UID>.middleware.io")
                .rumAccessToken("<MW_RUM_ACCESS_TOKEN>")
                .serviceName("my-ios-app")
                .projectName("My-iOS-App")
                .deploymentEnvironment("PROD")
                .globalAttributes([
                    "app.version": Bundle.main.object(
                        forInfoDictionaryKey: "CFBundleShortVersionString"
                    ) as? String ?? ""
                ])
                .build()
        } catch {
            print("Middleware RUM initialization failed: \(error)")
        }

        return true
    }
}
```

Replace the placeholders with your Middleware credentials.

| Parameter | Required | Description |
| --- | --- | --- |
| `target` | Yes | Middleware ingestion endpoint |
| `rumAccessToken` | Yes | RUM access token generated during setup |
| `serviceName` | Yes | Service name used to identify the application |
| `projectName` | Yes | Project name associated with the application |
| `deploymentEnvironment` | No | Environment, such as `PROD` or `DEV` |
| `globalAttributes` | No | Custom attributes such as application version |

> **Note:** **Note**: If your application requires user consent before collecting telemetry, initialize the SDK only after consent is granted.

#### 4 Run and verify

Build and run your application on an iOS simulator or physical device.

1. Open the application.
2. Navigate between screens and trigger a few network requests.
3. Go to **RUM → Session Explorer** in Middleware.
4. Verify that your application sessions appear.

Read more about [RUM explorer](https://docs.middleware.io/features/rum/session-explorer) and see what data to monitor for frontend performance.

## Enable or disable monitoring features

Crash reporting, HTTP instrumentation, and slow rendering detection are enabled by default.

To disable specific features, add the corresponding methods during initialization:

```swift
try MiddlewareRumBuilder()
    .target("https://<MW_UID>.middleware.io")
    .rumAccessToken("<MW_RUM_ACCESS_TOKEN>")
    .serviceName("my-ios-app")
    .projectName("My-iOS-App")
    .disableCrashReportingInstrumentation()
    .disableNetworkMonitoring()
    .disableSlowRenderingDetection()
    .build()
```

Only include the disable methods for features you don't want to collect.

| Method | Description |
| --- | --- |
| `disableCrashReportingInstrumentation()` | Disables automatic crash reporting |
| `disableNetworkMonitoring()` | Disables HTTP request instrumentation |
| `disableSlowRenderingDetection()` | Disables slow and frozen frame detection |
| `slowFrameDetectionThresholdMs(Double)` | Configures the slow frame threshold; default is 16.7 ms |
| `frozenFrameDetectionThresholdMs(Double)` | Configures the frozen frame threshold; default is 700 ms |

## Configure Session Replay

Session Replay is enabled by default and starts automatically when the SDK initializes.

It records user activity and screen changes to help investigate application issues.

### Configure recording quality and privacy

Use `RecordingOptions` to configure recording frequency, quality, and masking.

```swift
try MiddlewareRumBuilder()
    .target("https://<MW_UID>.middleware.io")
    .rumAccessToken("<MW_RUM_ACCESS_TOKEN>")
    .serviceName("my-ios-app")
    .projectName("My-iOS-App")
    .recordingOptions(
        RecordingOptions()
            .setFrequency(.standard)
            .setQuality(.standard)
            .setMaskAllTextInputs(true)
            .setMaskAllImages(true)
    )
    .build()
```

| Option | Description |
| --- | --- |
| `setFrequency()` | Recording frequency: `low`, `standard`, or `high` |
| `setQuality()` | Recording quality: `low`, `standard`, or `high` |
| `setMaskAllTextInputs()` | Masks text input values; enabled by default |
| `setMaskAllImages()` | Masks images; enabled by default |

### Disable Session Replay

To collect RUM telemetry without recording user sessions, add:

```swift
.disableRecording()
```

### Session recording limits

- **Maximum session duration**: 4 hours.
- **Idle timeout**: 15 minutes.
- **Default**: Session Replay enabled.

After the idle timeout, new user activity starts a new session.

## Mask sensitive information

Middleware masks sensitive text inputs and images by default. You can also mask specific UI elements that contain payment details, authentication information, or other sensitive content.

### SwiftUI

Use the `.sensitive()` modifier:

```swift
Text("Sensitive account information")
    .sensitive()
```

### UIKit

Exclude a view from Session Replay:

```swift
MiddlewareRum.addIgnoredView(sensitiveView)
```

Alternatively, mark a view using its accessibility identifier:

```swift
cardNumberField.accessibilityIdentifier = "mw-no-capture"
```

Supported identifiers:

- `mw-no-capture` — Always masks the view.
- `mw-no-mask` — Excludes the view from masking.

**Important**: Secure text fields and sensitive textContentType fields, such as passwords, credit card details, and one-time codes, remain masked regardless of the configuration.

Masking is applied on the device before session recording data is uploaded.

## Configure distributed tracing

Distributed tracing connects iOS network requests with backend APM traces.

The SDK automatically instruments `URLSession` and injects W3C `traceparent` headers into outgoing requests.

No additional HTTP client instrumentation is required.

### Prerequisites

- Middleware APM instrumentation must be enabled on your backend.
- Backend services must support W3C Trace Context.
- Network monitoring must be enabled in the iOS SDK.

### Restrict trace propagation targets

By default, trace headers are added to outgoing requests, excluding Middleware ingestion endpoints.

To restrict propagation to your backend domains:

```swift
try MiddlewareRumBuilder()
    .target("https://<MW_UID>.middleware.io")
    .rumAccessToken("<MW_RUM_ACCESS_TOKEN>")
    .serviceName("my-ios-app")
    .projectName("My-iOS-App")
    .tracePropagationTargets([
        "api\\.example\\.com",
        "checkout\\.example\\.com"
    ])
    .build()
```

Requests to other domains are still monitored but do not receive tracing headers.

Passing an empty array disables trace propagation.

### Verify trace correlation

1. Open your application and trigger a backend API request.
2. Go to **RUM → Session Explorer**.
3. Open the session and select the network request.
4. Follow the associated backend trace.

If the request has a trace ID but no backend spans, verify that your backend is instrumented and accepts W3C Trace Context.

## Add custom logs and errors

### Custom logs

Use the SDK to capture application-specific logs:

```swift
MiddlewareRum.info("User opened checkout")
MiddlewareRum.debug("Loading payment details")
MiddlewareRum.warning("API response delayed")
MiddlewareRum.error("Payment request failed")
MiddlewareRum.critical("Unexpected application failure")
```

### Report custom errors

Record application errors for investigation:

```swift
MiddlewareRum.addError("Unable to process payment")
```

### Report handled exceptions

Application crashes are captured automatically. You can report handled exceptions manually:

```swift
MiddlewareRum.addException(
    e: NSException(
        name: NSExceptionName(rawValue: "RuntimeException"),
        reason: "Payment processing failed"
    )
)
```

## Add custom attributes

Use global attributes to filter sessions by application version, environment, or user group.

```swift
MiddlewareRum.setGlobalAttributes([
    "app.version": "1.0.0",
    "user.type": "premium"
])
```

Prefer stable, non-sensitive values. Avoid sending passwords, tokens, or personal information.

### Set a custom screen name

To identify screens using application-specific names:

```swift
MiddlewareRum.setScreenName("checkout")
```

This is useful when investigating navigation or grouping events by screen.

## Instrument WebView content

If your application uses a `WKWebView`, you can connect Browser RUM with Mobile RUM to investigate hybrid user journeys.

```swift
MiddlewareRum.integrateWebViewWithBrowserRum(view: webView)
```

Use this on the active WebView instance.

The embedded web application should also have the Middleware Browser RUM SDK installed for browser-side telemetry.

## Configuration reference

All methods accepted by `MiddlewareRumBuilder()`:

| Method | Description |
| --- | --- |
| `target(String)` | Sets the Middleware ingestion endpoint |
| `rumAccessToken(String)` | Sets the RUM access token |
| `serviceName(String)` | Sets the application service name |
| `projectName(String)` | Sets the project name |
| `deploymentEnvironment(String)` | Sets the deployment environment |
| `globalAttributes(...)` | Adds custom attributes during initialization |
| `tracePropagationTargets([String])` | Restricts trace propagation to selected URLs |
| `recordingOptions(...)` | Configures Session Replay |
| `disableRecording()` | Disables Session Replay |
| `disableCrashReportingInstrumentation()` | Disables automatic crash reporting |
| `disableNetworkMonitoring()` | Disables HTTP instrumentation |
| `disableSlowRenderingDetection()` | Disables slow and frozen frame detection |
| `slowFrameDetectionThresholdMs(Double)` | Sets the slow frame threshold |
| `frozenFrameDetectionThresholdMs(Double)` | Sets the frozen frame threshold |

## Troubleshooting

### No RUM data appears

If your application is running but telemetry does not appear:

- Verify that the SDK is installed and imported correctly.
- Confirm that `MiddlewareRumBuilder().build()` runs during application startup.
- Check the RUM access token and target URL.
- Verify that the device can connect to Middleware over HTTPS.
- Review the Xcode console for initialization or export errors.

### Network requests are missing

If sessions appear but HTTP requests are not collected:

- Confirm that `disableNetworkMonitoring()` is not enabled.
- Verify that requests use URLSession or a networking library built on it.
- Check whether the requests are sent to excluded Middleware ingestion endpoints.

### Backend traces are not correlated

If network requests appear but backend traces are missing:

- Verify that backend APM instrumentation is enabled.
- Confirm that the backend accepts W3C Trace Context.
- Check that `tracePropagationTargets()` matches your backend domains.
- Ensure that proxies or gateways do not remove the `traceparent` header.

### Session Replay is missing

If sessions appear without recordings:

- Verify that disableRecording() is not enabled.
- Check that SDK initialization completes successfully.
- Confirm that recording is permitted by your application's consent settings.
- Review SDK logs for recording or upload errors.

### Sensitive information appears in recordings

- Verify that text and image masking is enabled.
- Use `.sensitive()` for SwiftUI views.
- Use `MiddlewareRum.addIgnoredView()` for UIKit views.
- Mark sensitive fields with `mw-no-capture`.
- Review masking whenever the application UI changes.

### High slow or frozen frame counts

The SDK reports:

- **Slow frames**: Rendering time above 16.7 ms.
- **Frozen frames**: Rendering time above 700 ms.

Use Xcode Instruments, including Time Profiler and Core Animation, to identify expensive main-thread work or rendering operations.

### HTTPS requests are blocked

iOS App Transport Security (ATS) blocks cleartext HTTP connections by default.

Use HTTPS for your Middleware ingestion endpoint and backend APIs. For development environments requiring HTTP, configure scoped ATS exceptions in `Info.plist`.

### Build errors

- If Xcode can't resolve the package, go to **File → Packages → Reset Package Caches** and resolve again.
- For CocoaPods, run `pod install` and open the `.xcworkspace` file, not the `.xcodeproj`.
- If CocoaPods can't find or upgrade `MiddlewareRum`, check both sources are in your Podfile and run `pod update MiddlewareRum`.
- If your Podfile uses `use_frameworks!`, link `MiddlewareRum` statically.
- Verify that the deployment target is iOS 13 or later.

If the issue persists, contact Middleware Support at support@middleware.io.

Need assistance or want to learn more about Middleware? Get in touch with us via our Contact Us page or join our Slack channel.
