Instrument SwiftUI controls

OneAgent for iOS version 8.249+

After instrumenting your mobile app with OneAgent for iOS, you might also want to instrument your app's SwiftUI controls. This page provides additional information on how to set up your project, update our SwiftUI instrumentor, overcome some known limitations, and more.

To instrument SwiftUI controls, our SwiftUI instrumentor adds additional code to your project's source code (*.swift files) during the build process. This code observes the state of UI elements and notifies the OneAgent for iOS about any updates. After the build process is completed, all changes to your project's source code are reverted.

For detailed information on actions performed by the SwiftUI instrumentor and a copy of the altered code files, check the dynatrace_instrumented directory. The SwiftUI instrumentor creates backups of the instrumented files and generated logs in ZIP archive format.

Requirements

Supported controls

We support the instrumentation of the following SwiftUI controls and views.

When required, you can globally or locally exclude certain controls from the SwiftUI instrumentation process.

Supported methods

OneAgent for iOS version 8.265+

We support the instrumentation of the following SwiftUI methods:

The following data is reported every time the closure of one of the supported methods is executed:

  • Method name
  • Type of view the method was attached to
  • Parent view name

Lifecycle monitoring

OneAgent for iOS version 8.265+

The SwiftUI instrumentor collects data on the following events:

Required steps

To instrument your app's SwiftUI controls, make sure you've completed the following steps:

Manage SwiftUI instrumentor

Install the instrumentor

To instrument your app's SwiftUI controls, install the Dynatrace SwiftUI instrumentor. You can do that via Homebrew or manually.

OneAgent for iOS should already be set up for your project. Also, don't forget to back up your project before installing the instrumentor.

If an error occurs during the implementation, check the Xcode build log or the instrumentation log for detailed information on the error. For additional hints, refer to Mobile applications: Issues with SwiftUI instrumentation in the Dynatrace Community.

When you build your app, you should do that with the scheme that you've instrumented.

Update the instrumentor

When the new version of the SwiftUI instrumentor is available, you can update it via Homebrew or manually.

If you see the following build warning, you also need to update the build scripts that were integrated during the installation of the Dynatrace SwiftUI instrumentor.

Dynatrace: There is an upgrade for your project instrumentation. Please execute "DTSwiftInstrumentor project-upgrade <PROJECT.xcodeproj>" to upgrade your project

Run the suggested command to update the build scripts, and then save the changes made to your project file.

Uninstall the instrumentor

If you no longer need the Dynatrace SwiftUI instrumentor, you can delete it from your system via Homebrew, or you can manually remove it from your project.

Check SwiftUI instrumentation diff

OneAgent for iOS version 8.257+

To check the difference between your original code and the code modified by the SwiftUI instrumentor, run one of the following commands:

  • From the project root:
    • DTSwiftInstrumentor diff if you installed the instrumentor via Homebrew
    • .dynatrace/DTSwiftInstrumentor diff if you installed the instrumentor manually
  • From any directory
    • DTSwiftInstrumentor diff <root-project-dir-path>

Known limitations

Instrumentation of custom SwiftUI controls not supported

Currently, Dynatrace doesn't support the instrumentation of custom SwiftUI controls. For the list of SwiftUI controls that you can instrument, see Supported controls.

Issue with previews in Xcode

When a simulator build included the SwiftUI instrumentation, the previews were not loaded in Xcode. As a workaround, we disabled the SwiftUI instrumentation for simulator builds. If you want to add the SwiftUI instrumentation to simulator builds, see Instrument simulator builds.

SwiftUI 2.0+ only

Dynatrace supports SwiftUI 2.0+ instrumentation because the onChange listener is unavailable in earlier SwiftUI releases. For this reason, a deployment target needs to be of iOS 14+.

Longer build time

Unlike the OneAgent for iOS that modifies your mobile app in memory during runtime, the SwiftUI instrumentor alters your project's source code during build time. For this reason, the SwiftUI instrumentation process has a noticeable impact on the build time.

To decrease the build time

  • Build only for Device. If you've decided to instrument simulator builds, disable that feature.
  • Don't run SwiftUI instrumentation on every possible build. We suggest running SwiftUI instrumentation on branches like main or release.

watchOS incompatibility

It's impossible to compile a project containing files that are added to a watchOS target, as there is no OneAgent for watchOS. In this case, manually exclude all files that are shared with or part of a watchOS target.

tvOS not supported

Currently, there is no official support for tvOS SwiftUI builds.

Configure SwiftUI instrumentation

Enable Session Replay on crashes

Session Replay on crashes can capture and visually replay the actions that your application user performed before a crash occurred.

To turn this feature on, see Enable Session Replay for SwiftUI apps.

Globally exclude controls from SwiftUI instrumentation

OneAgent for iOS version 8.263+

The Dynatrace SwiftUI instrumentor instruments all UI elements listed under Supported controls. When required, you can globally exclude certain controls from the SwiftUI instrumentation process.

To globally exclude controls from the SwiftUI instrumentation, add the DTXSwiftUIExcludedControls configuration key to your project's Info.plist file.

<key>DTXExcludedSwiftUIFiles</key>
<array>
<string>Button</string>
<string>Slider</string>
</array>

Locally exclude controls from SwiftUI instrumentation

OneAgent for iOS version 8.263+

With the withCustomInstrumentationConfig(.skipInstrumentation) function, you can locally exclude controls from SwiftUI instrumentation.

In contrast to the DTXSwiftUIExcludedControls configuration key, which allows you to prevent the instrumentation of all instances of a specified control type, the withCustomInstrumentationConfig(.skipInstrumentation) function can be used to exclude a specific instance of a control type. You can apply this function directly to a control or, to exclude multiple control instances, to a container.

Follow these guidelines when applying the withCustomInstrumentationConfig(.skipInstrumentation) function:

  • To use the function, first add the import Dynatrace import statement.

  • Add withCustomInstrumentationConfig(.skipInstrumentation) as the last modifier in the list of the view modifiers. For example:

    Button("Login", action: { /* perform login */ })
    .padding()
    .background(Color.red)
    .frame(width: 40)
    .withCustomInstrumentationConfig(.skipInstrumentation)

Exclude a single control

Use the following code to locally exclude a single control from the SwiftUI instrumentation:

import Dynatrace
Button("Login", action: { /* perform login */ })
.withCustomInstrumentationConfig(.skipInstrumentation)

Exclude multiple controls

To locally exclude a group of controls, apply the withCustomInstrumentationConfig(.skipInstrumentation) function to their parent container.

import Dynatrace
HStack {
Button("Login", action: { /* perform login */ })
Button("Register", action: { /* perform registration */ })
}.withCustomInstrumentationConfig(.skipInstrumentation)

Exclude files from SwiftUI instrumentation

By default, the Dynatrace SwiftUI instrumentor processes all files with a .swift file extension, but it only instruments files that contain the supported controls. When required, you can exclude certain files and directories from the SwiftUI instrumentation process.

To exclude files and directories from the SwiftUI instrumentation

  1. Add the DTXExcludedSwiftUIFiles configuration key to your project's Info.plist file.

  2. List relative paths of all files and directories that you don't want to instrument. The paths should be relative to the project root, which is the directory where the .xcodeproj file is located.

    <key>DTXExcludedSwiftUIFiles</key>
    <array>
    <string>relative/file/path/</string>
    <string>relative/file.swift</string>
    </array>

The instrumentation log, which is available after each build, contains the list of files and directories that should be excluded from the SwiftUI instrumentation. The instrumentation log also shows you if a file or directory was excluded during the instrumentation process.

Instrument simulator builds

We disabled the SwiftUI instrumentation for simulator builds to overcome an issue with the previews in Xcode.

To enable the SwiftUI instrumentation for simulator builds, add the DTXSwiftUIInstrumentSimulatorBuilds configuration key to your project's Info.plist file and set this key to true.

<key>DTXSwiftUIInstrumentSimulatorBuilds</key>
<true/>

Create builds for unsupported deployment targets

Our SwiftUI instrumentor generates SwiftUI 2.0+ compatible code that only runs on devices with iOS 14+. The attempt to generate builds for deployment targets of iOS 13 and earlier will fail.

To override this check, add the DTXSwiftUIIgnoreDeploymentTarget configuration key to your project's Info.plist file and set this key to true.

<key>DTXSwiftUIIgnoreDeploymentTarget</key>
<true/>

Enable line number mapping for Objective-C projects

Crash reports that are available in Dynatrace are not based on the source code of your project. These reports are based on the altered code that Dynatrace generates during instrumentation. This is why line number mapping is added to your project during instrumentation and later passed to Dynatrace on app launch. Otherwise, the line numbers in crash reports would be incorrect.

By default, the Dynatrace SwiftUI instrumentor generates a line number mapping and inserts it into your project's main class. This happens automatically for projects with a Swift main class, but not for legacy Objective-C projects. For such projects, you'll get an error, and our SwiftUI instrumentor won't instrument your mobile app.

To enable line number mapping for Objective-C projects

  1. Add the DTXSwiftUIManualPlaceholder configuration key to your project's Info.plist file and set this key to true.

    <key>DTXSwiftUIManualPlaceholder</key>
    <true/>
  2. Add the special AppDelegate.m placeholder to the main class.

  3. Add the [Dynatrace handoverInstrumentorConfig:@{kDTXSwiftMappingJson: @"_DYNATRACE_SWIFTUI_MAPPING_PLACEHOLDER_"}]; line to the main class in either the init or the didFinishLaunchingWithOptions method.

    During the build, the SwiftUI instrumentor replaces part of this line with the generated line number mapping.

Enable automatic log cleanup

OneAgent for iOS version 8.257+

After each build, the SwiftUI instrumentor creates backups of the instrumented files and generated logs, which are stored under dynatrace_instrumented. By default, these files are not deleted, and the total size of the directory will grow over time. For this reason, we recommend that you to enable the automatic log cleanup.

If you add both keys to the Info.plist file, the DTXCleanSwiftUILogsByAgeDays key takes precedence.

Troubleshooting

We're still working on improving the SwiftUI instrumentation process. If you face any issues while instrumenting SwiftUI controls, refer to Mobile applications: Issues with SwiftUI instrumentation in the Dynatrace Community.