Using the SDK with Compose Multiplatform

The Scandit Data Capture SDK ships a set of Compose-Multiplatform companion modules (scandit-kmp-datacapture-*-compose) that expose the capture views and modes as @Composable functions. They let you place a fully-wired data capture view directly in your composition and drive it with state, instead of constructing and managing the imperative views and overlays yourself.

The companions are additive: the base modules stay Compose-free, so non-Compose consumers (SwiftUI, XML/View, plain KMP) are unaffected. Add the -compose module for each feature you use (for example scandit-kmp-datacapture-core-compose and scandit-kmp-datacapture-barcode-compose) alongside the base modules.

This page covers the core view that every capture mode builds on. Each capture mode adds its own composables — see the Compose Multiplatform Views page in the Barcode Capture, ID Capture and Label Capture sections.

Dependency

Add the core Compose companion to your commonMain source set (it pulls in the base core module transitively):

commonMain.dependencies {
    implementation("com.scandit.datacapture.kmp:core-compose:<version>")
}

The core view

The DataCaptureView composable renders the camera preview and any overlays and controls you pass to it. Two helper composables wire up the supporting objects and tie their lifecycle to the composition:

  • rememberDataCaptureContext(licenseKey) creates and remembers a DataCaptureContext.

  • rememberCamera(context, position) creates a Camera, wires it as the frame source of the context, and turns it on/off with the composition lifecycle.

@Composable
fun ScannerScreen() {
    val context = rememberDataCaptureContext(licenseKey = LICENSE_KEY)
    val camera = rememberCamera(context)

    val barcodeCapture = remember(context) {
        BarcodeCapture.forContext(context, BarcodeCaptureSettings.barcodeCaptureSettings())
            .also { it.isEnabled = true }
    }
    val overlay = remember(barcodeCapture) {
        BarcodeCaptureOverlay.withBarcodeCapture(barcodeCapture)
    }

    DataCaptureView(
        context = context,
        modifier = Modifier.fillMaxSize(),
        overlays = listOf(overlay),
    )
}

Controls (torch, camera switch, zoom) are placed declaratively with a list of ControlPlacement, each pinning a control to an Anchor with an optional offset:

DataCaptureView(
    context = context,
    controls = listOf(
        ControlPlacement(TorchSwitchControl(), Anchor.TOP_RIGHT, offset = null),
    ),
)

Focus and zoom gestures, the logo style and anchor, the scan-area margins and the point of interest are all parameters of the DataCaptureView composable and default to the same values as the imperative view.