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 aDataCaptureContext.rememberCamera(context, position)creates aCamera, 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.