This page covers what you can change after iOS Monitoring Setup is working. Configuration is split in two: Atatus.Configuration labels your data and controls the transport, and RUM.Configuration controls what RUM collects. Nothing here is required. Each option has a default, so add only what you need.

Identity and transport

These options are passed to Atatus.initialize() and apply to every product:

Tune batching

Batch size and upload frequency trade data latency against radio use. Larger, less frequent batches amortize each radio wake-up across more events:
Use .large with .rare when battery consumption is the constraint, and .small with .frequent during development, where fast feedback matters more than efficiency.

Encrypt data at rest

Events waiting to be uploaded are stored in the application’s cache directory. To encrypt them, pass an object that implements DataEncryption:

RUM options

Every option on RUM.Configuration, with the value it takes when you leave it out: The performance options are covered in Mobile Vitals, and the network options in Network Tracking.

Track views automatically

A views predicate decides which screens become RUM views and what they are called. Without one, no views are tracked at all.

UIKit

DefaultUIKitRUMViewsPredicate tracks each view controller as a screen, named after its class, such as MyApp.CheckoutViewController. It skips UIKit’s own container controllers, so UINavigationController and UITabBarController do not appear as screens, and it skips SwiftUI hosting controllers, which the SwiftUI predicate handles instead. A subclass of your own is always tracked, including a subclass of a container controller. Class names make poor screen names in a dashboard. Write a predicate to name them yourself:
Returning nil leaves a screen untracked. isUntrackedModal: true is for an overlay you do not want recorded as a screen: the view underneath stops while it is up, and restarts when it is dismissed, so its time is not counted as time on the screen behind it.
path is not an initializer parameter. Create the RUMView first, then set view.path as the example does. When you leave it unset, the path falls back to the class name.

SwiftUI

DefaultSwiftUIRUMViewsPredicate detects SwiftUI screens by inspecting the hosting controller, and names them after the view type it finds:
SwiftUI view detection is experimental. It reads SwiftUI’s internal structures, so names vary with the iOS version, and a screen it cannot resolve is reported under a generic fallback name. For screens that matter, name them yourself with .trackRUMView(name:) as shown in iOS Monitoring Setup, and do not apply the modifier to a screen the predicate already detects, because the view is then counted twice.
To rename what the predicate finds, implement it yourself:

Track a view manually

Manual tracking is the most reliable option when the predicates do not fit your navigation:

Track user actions automatically

DefaultUIKitRUMActionsPredicate reports taps. It reports a tap only when it lands on a control, a table view cell, a collection view cell, or an alert action, so taps on plain views and labels are not reported. Taps on the system keyboard are dropped for privacy. Action names come from the view: if it has an accessibilityIdentifier, the name is the class plus that identifier, such as UIButton(checkout-button). Otherwise it is the class name alone.
Set accessibilityIdentifier on the controls you care about. It is the only way to get readable action names from the default predicate, and it costs nothing because it does not affect the interface.
A custom predicate can rename an action or return nil to drop it. It cannot widen what is captured, because the filtering above happens before the predicate is asked:
On tvOS the predicate is press based rather than touch based, and reports select, menu, and play or pause presses as click actions.

Scroll and swipe

Scroll and swipe actions are reported for UIScrollView, UITableView, and UICollectionView whenever a UIKit actions predicate is set. The SDK decides which of the two it was from how fast the finger was moving when it left the screen, and records the direction. Turn it off with the feature flag:
This is available on iOS and iPadOS.

Frustration signals

With trackFrustrations on, which is the default, a tap followed by an error is reported as an error tap. That is the one frustration signal the iOS SDK detects, and it rolls up into a frustration count per view.

Identify your users

Attaching a user to the session lets you find every session, error, and request belonging to one person:
Only id is required. Add fields you learn later without repeating the rest:
Clear the user on sign-out, so the next session is not attributed to the person who signed out:
User information is attached to every event from the moment you set it, so set it as soon as you know who the user is, and treat it as data leaving the device. Send an identifier you can resolve internally rather than personal data you do not need in a dashboard.
For business-to-business applications, the account APIs record the organization a user belongs to, alongside the user:
trackAnonymousUser is on by default and keeps a random per-install identifier, so sessions from the same device are counted as one user even before sign-in. Turn it off if you do not want that identifier stored:

Attach your own attributes

Global attributes are attached to every RUM event from the point you add them:
View attributes apply to the active view only, which is the right scope for something that describes one screen:

Send custom events

Views

Track a screen yourself when the automatic predicates cannot name it correctly, for example a screen rendered by a single container controller:
A view started with a key must be stopped with the same key. Starting a new view stops the previous one, so you do not need to pair them when you navigate forward.

Actions

Report an action the SDK cannot see, such as a gesture handled by your own recognizer:
addAction is for an instantaneous action. For one with a duration, bracket it:
The action types are .tap, .click, .scroll, .swipe, and .custom.

Errors

Report a handled error, so a failure your code recovers from is still visible:
See Error Tracking for error sources, fingerprints, and crash reporting.

Resources

Report a request made by a client the SDK cannot instrument. See Network Tracking.

Feature flag evaluations

Record which variant a user received, so you can compare errors and performance between variants:
Report the evaluation wherever your flag library resolves it, whichever library that is. Evaluations are attached to the active view and to the errors recorded in it, and are cleared when the view stops, so report them on each screen that depends on the flag rather than once at launch.

Modify or drop events

An event mapper runs on every event of its type before it is uploaded. Use it to redact a URL, rename a view, or drop an event you do not want:
The view mapper must return an event, so a view cannot be dropped. The resource, action, error, and long task mappers can return nil to drop the event. Mappers run on a background thread, once per event, so keep them fast and free of side effects.

Control the session

Read the current session ID to attach it to a support ticket or your own logs:
End the session yourself, for example on sign-out, so the next user’s activity starts a new one:
To react to each new session, pass onSessionStart:

Manage stored data

These apply to data the SDK has collected but not yet uploaded:
Atatus.isInitialized() reports whether an instance is running, which is useful in a shared framework that must not initialize twice.

Run more than one instance

A single instance covers almost every application. If you need to send data to two accounts or two regions, name each instance and pass it to each product:
Every API that touches the SDK takes an in core: parameter, which defaults to the unnamed instance.

Debugging

Print what the SDK is doing, in debug builds only:
To see view and action boundaries on the device while you work, turn on the RUM debug overlay:
Both are debugging aids. Leave them out of release builds, because the overlay draws over your interface and verbose logging prints SDK internals to the device console.

Next steps