Skip to main content

View Capture Service

Overview


The ViewCaptureService is in charge of automatically instrumenting UIViewController load and render times. You can customize the service behavior by passing a custom ViewCaptureService when setting up the Embrace SDK:

let services = CaptureServiceBuilder()
.add(.view(options: ViewCaptureService.Options(instrumentVisibility: true, instrumentFirstRender: true)))
.addDefaults()
.build()

try Embrace
.setup(
options: Embrace.Options(
appId: "APPID",
captureServices: services
//...other options
)
)
.start()

Screen visibility

This feature is enabled by setting instrumentVisibility to true in the ViewCaptureService.Options. The service will generate spans that start when a UIViewController appears (viewDidAppear) and ends when it disappears (viewDidDisappear).

Time to First Render

This feature is enabled by setting instrumentFirstRender to true in the ViewCaptureService.Options.

The service will generate spans that start when a UIViewController is loaded (viewDidLoad) and ends when it becomes visible for the first time (viewDidAppear). The service will also generate child spans measuring several steps in the process: viewDidLoad, viewWillAppear and viewDidAppear.

info

If the UIViewController disappears before it finishes loading, the spans status will be set to .error with the .userAbandon code.

Time to Interactive

This feature is enabled by setting instrumentFirstRender to true in the ViewCaptureService.Options, and making a UIViewController implement the InteractableViewController protocol.

The service will generate spans that start when a UIViewController is loaded (viewDidLoad) and ends when it is flagged as ready for interaction (setInteractionReady()). If you implement this protocol in one of your UIViewControllers, you need to call setInteractionReady() when the screen is ready to be interacted by the user.

Example:

class MyViewController: UIViewController, InteractableViewController {

override func viewDidLoad() {
super.viewDidLoad()

// some async operation
MyDataFetcher.fetch { [weak self] data in
self?.loadData(data)
self?.setInteractionReady()
}
}
}
info

If the UIViewController disappears before it is flagged as ready for interaction, the spans status will be set to .error with the .userAbandon code.

Custom child spans

When the first render instrumentation is enabled, you can also add custom child spans to the ones automatically generated by the service. You'll need to implement the InstrumentableViewController protocol and use the buildChildSpan or recordCompletedChildSpan methods

Example:

class MyViewController: UIViewController, InstrumentableViewController {

override func viewDidLoad() {
super.viewDidLoad()

let childSpan = buildChildSpan(name: "data-fetch").startSpan()

// some async operation
MyDataFetcher.fetch { [weak self] data in
self?.loadData(data)
childSpan.end()
}
}
}