Production Metrics

Defined in framework ScanditCaptureCore

enum MetricGroup

Added in version 8.7.0

A group of signals that production metrics can emit. Selecting a group in MetricsSettings emits its events.

scan

Added in version 8.7.0

One event per recognition.

msar

Added in version 8.7.0

One event per MatrixScan AR frame.

frame

Added in version 8.7.0

One event per sampled processed frame.

environment

Added in version 8.7.0

Ambient and device conditions, sampled periodically.

camera

Added in version 8.7.0

Camera lifecycle transitions.

frameCapture

Added in version 8.7.0

Captured frames and their images.

lifecycle

Added in version 8.7.0

The app leaving and returning to the foreground.

context

Added in version 8.7.0

Data capture context status changes.

cameraConfig

Added in version 8.7.0

Camera configuration snapshots.

labelConfig

Added in version 8.7.0

Label capture configuration snapshots. Their payload is not public API yet, so these events reach a sink with no payload set.

enum SensitiveField

Added in version 8.7.0

A field withheld from events unless opted into.

scanData

Added in version 8.7.0

The recognized barcode content.

frameImage

Added in version 8.7.0

The pixels of a captured frame, delivered alongside the frame-capture row.

MetricsSink
protocol MetricsSink : NSObjectProtocol

Added in version 8.7.0

Consumer of production metrics, registered with ProductionMetrics.addSink(_:).

These three methods are the whole interface. New signals arrive as new payloads on MetricEvent, which a sink that does not know them ignores.

An implementation has to be thread-safe. Event deliveries run on the metrics queue rather than on the thread that emitted the event; flush runs on whichever thread asked for it, including the one that disposes of the data capture context, so two calls to one sink can overlap.

onMetricEvents(_:)
open func onMetricEvents(_ events: Array<MetricEvent>) -> Void

Added in version 8.7.0

Delivers a batch of events. Every event of a session follows that session’s config event, the one whose MetricEvent.config is set. Events carry no sequence number, so a sink that splits its output across several destinations is the party that has to preserve the order it received them in.

onFrameCaptured(_:)
optional func onFrameCaptured(_ capture: FrameCapture) -> Void

Added in version 8.7.0

Delivers the pixels for a FrameCaptureMetrics row, keyed to it by FrameCapture.captureId. On Android FrameCapture.data is a view that is valid only for the duration of this call, so copy it to keep the image; on iOS the capture owns the bytes for as long as you hold it.

flush()
optional func flush() -> Void

Added in version 8.7.0

Requests that everything buffered so far reaches its destination. Called when the session ends, so a sink that batches has one guaranteed opportunity to finish. A backgrounded app can be terminated without its session ending, so it is also called each time the app leaves the foreground, and one session can see several calls.

ProductionMetrics
open class ProductionMetrics : NSObject

Added in version 8.7.0

On-device production metrics for one DataCaptureContext. The signal groups selected in MetricsSettings are delivered as MetricEvent instances to every registered MetricsSink; the bundled CsvMetricsSink writes them to disk, and any other sink receives them in the app.

A context runs one instance and keeps it alive: creating another one through init(context:settings:) replaces it, sinks included. Reconfigure the instance through applySettings(_:) and isEnabled instead.

On Android the context also holds this object, so it stays reachable. On iOS it is only a handle and the context exposes no accessor for it, so keep it for as long as you want to call applySettings(_:), isEnabled or removeSink(_:); dropping it leaves the registered sinks receiving events with nothing left to reach them through.

Event deliveries to a sink run on the metrics queue rather than on the thread that emitted the event; flush runs on whichever thread asked for it, including the one that disposes of the context, so two calls to one sink can overlap.

init(context:settings:)
convenience init(context: DataCaptureContext, settings: MetricsSettings)

Added in version 8.7.0

Creates the production metrics of the context with the given settings, replacing the instance the context had before. Disabled until isEnabled is set.

isEnabled
open var isEnabled: Bool { get, set }

Added in version 8.7.0

Whether events are delivered. Nothing is delivered while false; enabling delivers the session’s config event before anything else. False when the instance is created.

settings
open var settings: MetricsSettings { get }

Added in version 8.7.0

The configuration in force. Changes to the returned object take effect through applySettings(_:).

applySettings(_:)
open func applySettings(_ settings: MetricsSettings) -> Void

Added in version 8.7.0

Applies the settings while running. A changed configuration is reported to every sink as a new config event.

addSink(_:)
open func addSink(_ sink: any MetricsSink) -> Void

Added in version 8.7.0

Registers the sink, if it is not registered already. While a session is running and enabled, the sink receives that session’s config event first.

On Android the registration keeps the sink alive until removeSink(_:). On iOS an app-provided sink is referenced weakly, like every listener of this SDK, so the app is what keeps it alive; the bundled CsvMetricsSink is the exception and keeps writing until removeSink(_:) even when the app drops it, but only the instance that was added removes it, so keep a reference to it for as long as it may need removing.

removeSink(_:)
open func removeSink(_ sink: any MetricsSink) -> Void

Added in version 8.7.0

Unregisters the sink. Events emitted before this call still reach it, followed by one call to MetricsSink.flush(); events emitted after it do not. The call returns without waiting for those deliveries, so keep a reference to the sink until its MetricsSink.flush() has run. A sink that was never registered is ignored.

MetricsSettings
open class MetricsSettings : NSObject, NSCopying

Added in version 8.7.0

Configuration of a ProductionMetrics: which signal groups are emitted, which sensitive fields their events may carry, and how often the frame group samples. It takes effect when passed to ProductionMetrics.init(context:settings:) or ProductionMetrics.applySettings(_:); changing it afterwards changes nothing until it is applied again.

init()
init()

Added in version 8.7.0

Creates settings that emit no group and carry no sensitive field.

enabledGroups
var enabledGroups: Set<MetricGroup> { get, set }

Added in version 8.7.0

The signal groups whose events are emitted. Empty by default.

enabledSensitiveFields
var enabledSensitiveFields: Set<SensitiveField> { get, set }

Added in version 8.7.0

The sensitive fields an emitted event may carry, such as the scanned data. Empty by default.

frameMetricsSampleRate
open var frameMetricsSampleRate: Int { get, set }

Added in version 8.7.0

Every Nth processed frame contributes a frame-metrics event. Values below 1 read as 1.

maxBufferedCaptures
open var maxBufferedCaptures: Int { get, set }

Added in version 8.7.0

Frame captures copied but not yet delivered. A recognition arriving while this many are in flight is dropped and counted. Held between 1 and 2.

maxCaptureBytes
open var maxCaptureBytes: Int64 { get, set }

Added in version 8.7.0

The largest capture delivered, in bytes. A larger frame is downscaled by a whole factor until it fits, never truncated, so a frame just over the cap arrives at half its width and height. Values below 1 read as 1.

CsvMetricsSink
open class CsvMetricsSink : NSObject, MetricsSink

Added in version 8.7.0

The bundled MetricsSink: writes one plaintext CSV file per signal group per session into its directory, which it creates on first write, and captured frame images next to them. Rows are buffered and reach disk in batches, on flush(), when the app leaves the foreground, and when the session ends. A file that grows too large is rotated and nothing bounds the directory’s total size. Write failures are logged and counted, never thrown.

init(directory:)
init(directory: URL)

Added in version 8.7.0

Creates a sink writing into the directory at the given file URL.

directory
open var directory: URL { get }

Added in version 8.7.0

The directory the sink writes into.

onMetricEvents(_:)
open func onMetricEvents(_ events: Array<MetricEvent>) -> Void

Added in version 8.7.0

Buffers the events as CSV rows.

onFrameCaptured(_:)
open func onFrameCaptured(_ capture: FrameCapture) -> Void

Added in version 8.7.0

Writes the captured image next to the CSV files.

flush()
open func flush() -> Void

Added in version 8.7.0

Writes the buffered rows to disk.