JPEG Screenshots

Configure periodic native iOS JPEG session capture and on-demand VisualTree screenshots for local host player and CLI workflows.

iOS exposes screenshots through two paths:

  • session JPEG capture streams periodic frames while a paired session is open
  • the VisualTree tool suite exposes on-demand ui.get_screenshot

Important: Screen capture will result in an FPS drop while the SDK renders, encodes, and transports frames. Use conservative interval, quality, and max-width settings, and disable session JPEG capture for trend-focused runs unless visual evidence is required.

Feature Suite Defaults

SetupSession JPEG captureOn-demand screenshots
initializeAndActivateAnsightSdk(...)Enabled every 2000ms, quality 60, max width 480, GPU-backed surface capture enabled.Registers AnsightToolsVisualTree.
AnsightCore manual setupDisabled until withSessionJpegCapture(...) is used.Unavailable until AnsightToolsVisualTree is registered.

Session Capture

let options = try AnsightOptions.createBuilder()
    .withSessionJpegCapture(
        intervalMilliseconds: 2000,
        quality: 60,
        maxWidth: 480,
        captureGpuBackedSurfaces: true,
        mode: .screenshotAndVisualTree,
        captureKeyboardPresence: true
    )
    .build()

Disable periodic capture when the run does not need screenshot history:

let options = try AnsightOptions.createBuilder()
    .withoutSessionJpegCapture()
    .build()

AnsightSessionJpegCaptureOptions properties:

PropertyMeaningDefault from withSessionJpegCapture()
intervalMillisecondsCapture interval while a pairing session is open. Values below 250ms are clamped.2000
qualityJPEG quality from 1 to 100.60
maxWidthOutput width cap. Height is derived from aspect ratio. Values above 8192 are clamped.480
captureGpuBackedSurfacesCaptures Metal, SceneKit, and similar GPU-backed surfaces. Set false to use a lower-overhead capture path when those surfaces are not needed.true
modeSelects screenshot-only, screenshot-aligned visual trees, or touch-triggered visual trees..screenshotOnly
captureKeyboardPresenceRecords whether the on-screen keyboard was present. It never records keyboard contents or dimensions.false

Capture modes:

  • .screenshotOnly sends periodic JPEG frames without an SDK visual-tree snapshot.
  • .screenshotAndVisualTree captures registered visual-tree sources with each app-owned screenshot and correlates them through the screenshot timestamp.
  • .screenshotWithVisualTreeOnTouch captures visual trees on touch down and touch up rather than for every frame. Move and cancel events do not trigger a tree.

Tree capture requires a registered session visual-tree provider. Touch-triggered mode also requires touch capture. Payloads follow the compact visual-tree v2 contract. Keyboard-presence metadata remains useful when the host owns Simulator screenshots.

Simulator Capture Ownership

The runtime advertises sessionJpegCaptureControlVersion: 1 in device.profile. The resident host can acknowledge the profile with sessionJpegCapture.mode: "host" and an optional source such as simctl.

In host mode, the SDK suspends its periodic in-app JPEG loop for that live session so the host can capture the Simulator externally. A missing response or mode: "app" keeps the configured SDK capture behavior. This negotiation is automatic and does not affect manual capture or ui.get_screenshot.

Manual Frame Capture

let result = await AnsightRuntime.shared.captureScreenFrame(
    options: AnsightSessionJpegCaptureOptions(
        quality: 60,
        maxWidth: 480,
        captureGpuBackedSurfaces: true
    )
)

On-Demand Screenshot Tool

Register the visual tree suite when you are not using the aggregate product:

import AnsightCore
import AnsightToolsVisualTree

try AnsightRuntime.shared.registerVisualTreeTools()

Most apps should use initializeAndActivateAnsightSdk(...), which registers the suite for you.

The tool id is ui.get_screenshot.

Arguments:

  • format: png or jpeg
  • quality: JPEG quality 1-100
  • maxWidth: optional width cap
  • annotateNodeIds: overlay node ids on the screenshot
  • afterScreenUpdates: wait for pending UIKit screen updates before rendering

Screenshot bytes are delivered out-of-band over Ansight binary transfer frames. The JSON result returns transfer metadata such as width, height, file name, MIME type, transfer id, and status.

Privacy And Overhead

Screenshots may contain credentials, personal data, notifications, and sensitive app state. Keep periodic capture scoped to local development and QA workflows.

Periodic and on-demand capture both reduce available frame time while rendering, encoding, and transfer work is happening. Set captureGpuBackedSurfaces to false only when the app does not need Metal, SceneKit, or similar surfaces in the captured image.