Instrumenting SwiftUI

If your app uses SwiftUI, view load measurements can be easily captured on your BugSnag dashboard using our SwiftUI package.

Installation

Using CocoaPods

Add the BugsnagPerformanceSwift pod to your Podfile:

pod 'BugsnagPerformanceSwift'

Run pod install after updating your Podfile.

Using Swift Package Manager

In your Project Navigator, add BugsnagPerformanceSwift.framework to the Frameworks, Libraries and Embedded Content section of your app’s target.

Manual Installation

Select your project in the Project Navigator, then add BugsnagPerformanceSwift.framework to the Frameworks, Libraries and Embedded Content section of your app’s target.

Usage

Tracing views

Create a BugsnagTracedView to wrap each view that you want to measure:

import SwiftUI
import BugsnagPerformanceSwift

struct ContentView: View {
    var body: some View {
        BugsnagTracedView("MyView"){
            VStack {
                // ...
            }
        }
    }
}

If no name is provided, the BugSnag SDK will use the view’s description.

Alternatively, you can call bugsnagTraced on an existing view to achieve the same effect:

import SwiftUI
import BugsnagPerformanceSwift

struct ContentView: View {
    var body: some View {
        VStack {
            // ...
        }
        .bugsnagTraced("MyView")
    }
}

The top-level instrumented view’s duration metrics will be aggregated in the “Screen loads” tab in the BugSnag dashboard. The SDK records the time from when its processing starts until the end of the work on the current main queue, which will mean the entire visible SwiftUI view hierarchy has loaded.

Measuring nested view components

You can also instrument nested view components. These will appear underneath the top-level span in the waterfall diagram of the span instance view on your dashboard. They are represented as a zero-length span at the moment their body property runs.

Controlling the end of view load spans

From a user’s perspective, the view is not loaded until it is ready for use. For this reason we provide APIs to allow you to defer the end of a view’s span – either until a condition is met or particular nested view components disappear (for example a loading spinner).

bugsnagDeferEndUntil takes a function that provides the conditions for closing the span:

import SwiftUI
import BugsnagPerformanceSwift

struct ContentView: View {
    var body: some View {
        VStack {
            // ...
        }
        .bugsnagDeferEndUntil {
            return !isLoading
        }
    }
}

bugsnagDeferEndUntilViewDisappears is added to nested components of a view to keep the span open until they disappear. This is intended to be placed on loading messages/spinners, for example:

import SwiftUI
import BugsnagPerformanceSwift

struct LoadingView: View {
    var body: some View {
        Text("Loading...")
        .bugsnagDeferEndUntilViewDisappears()
    }
}

struct ContentView: View {
    var body: some View {
        VStack {
            if data == nil {
                LoadingView()
            } else {
                Text("View loaded")
            }
            // ...
        }
        .bugsnagTraced("MyView")
    }
}