Compose Multiplatform Barcode Scanning Library
| Android | iOS | 
|---|---|
| 
       | 
    
       | 
  
KScan is a Compose Multiplatform library that makes it easy to scan barcodes in your apps
To integrate KScan into your project
Add the dependency in your common module's commonMain source set
implementation("io.github.ismai117:KScan:0.3.2")Android - MLKit
- Uses Google’s MLKit library for barcode scanning on Android
 
iOS - AVFoundation
- Utilizes Apple’s AVFoundation framework for camera setup and barcode scanning on iOS
 
Important: iOS requires you to add the "Privacy - Camera Usage Description" key to your Info.plist file inside xcode, you need to provide a reason for why you want to access the camera.
Basic Usage
To use KScan, simply add the ScannerView in your app like this:
if (showScanner) {
    ScannerView(
        codeTypes = listOf(
            BarcodeFormats.FORMAT_QR_CODE,
            BarcodeFormats.FORMAT_EAN_13,
        )
    ) { result ->
        when (result) {
            is BarcodeResult.OnSuccess -> {
                println("Barcode: ${result.barcode.data}, format: ${result.barcode.format}")
            }
            is BarcodeResult.OnFailed -> {
                println("error: ${result.exception.message}")
            }
            BarcodeResult.OnCanceled -> {
                println("scan canceled")
            }
        }
    }
}To dismiss the scanner, you need to manage your own state, set it to false in the right places inside the ScannerView block after you handle the results
if (showScanner) {
    ScannerView(
        codeTypes = listOf(
            BarcodeFormats.FORMAT_QR_CODE,
            BarcodeFormats.FORMAT_EAN_13,
        )
    ) { result ->
        when (result) {
            is BarcodeResult.OnSuccess -> {
                println("Barcode: ${result.barcode.data}, format: ${result.barcode.format}")
                showScanner = false
            }
            is BarcodeResult.OnFailed -> {
                println("Error: ${result.exception.message}")
                showScanner = false
            }
            BarcodeResult.OnCanceled -> {
                showScanner = false
            }
        }
    }
}If you want to remove the UI and just use the raw scanner, you can set the scannerUiOptions parameter to null
if (showScanner) {
    ScannerView(
        codeTypes = listOf(
            BarcodeFormats.FORMAT_QR_CODE,
            BarcodeFormats.FORMAT_EAN_13,
        ),
        scannerUiOptions = null
    ) { result ->
        when (result) {
            is BarcodeResult.OnSuccess -> {
                println("Barcode: ${result.barcode.data}, format: ${result.barcode.format}")
                showScanner = false
            }
            is BarcodeResult.OnFailed -> {
                println("Error: ${result.exception.message}")
                showScanner = false
            }
            BarcodeResult.OnCanceled -> {
                showScanner = false
            }
        }
    }
}To build a custom scanner UI with torch and zoom control, set scannerUiOptions = null and use a ScannerController.
val scannerController = remember { ScannerController() }
if (showScanner) {
    ScannerView(
        codeTypes = listOf(BarcodeFormat.FORMAT_ALL_FORMATS),
        scannerUiOptions = null,
        scannerController = scannerController
    ) { result ->
        when (result) {
            is BarcodeResult.OnSuccess -> {
                println("Barcode: ${result.barcode.data}, format: ${result.barcode.format}")
                showScanner = false
            }
            is BarcodeResult.OnFailed -> {
                println("Error: ${result.exception.message}")
                showScanner = false
            }
            BarcodeResult.OnCanceled -> {
                showScanner = false
            }
        }
    }
    Column(
        modifier = Modifier.align(Alignment.BottomCenter).padding(16.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Button(onClick = {
            scannerController.setTorch(!scannerController.torchEnabled)
        }) {
            Text("Torch ${if (scannerController.torchEnabled) "On" else "Off"}")
        }
        Slider(
            value = scannerController.zoomRatio,
            onValueChange = scannerController::setZoom,
            valueRange = 1f..scannerController.maxZoomRatio
        )
    }
}If you’d like to contribute, whether it’s fixing bugs, improving documentation, adding features, or helping with maintenance, your support is greatly appreciated!