Overview

The Genius Scan SDK includes a dedicated live code-scanning workflow that detects barcodes in real time via the device’s camera.

The SDK can detect a wide variety of barcodes: one-dimensional codes (1D codes) which everone refers to as barcodes and two-dimensional codes (2D codes), often abusively called QR-codes even though QR codes are just a subset of 2D codes.

This workflow handles all the low-level details of natively capturing one or more codes on any platform. When the capture session ends, it returns an array of codes and their values for you to process in whatever way you choose—the SDK deliberately leaves that post-processing up to you.

Unlike the document-centric readable-code detection already available, this module is tuned for continuous, real-time scanning scenarios.

Key Differences from Document-Based Scanning

Feature Document-Based Scanning Live Code Scanning
Primary Use Case Extract codes from scanned documents Real-time code detection
Detection Timing After document capture Continuous during camera preview
Output Document image + extracted codes Codes only
Performance Optimized for accuracy Optimized for speed
Typical Scenarios Form processing, document routing Warehouse scanning, inventory management

Use Cases

Warehouse Management

  • Scan package labels for sorting
  • Track inventory with barcode scanning
  • Verify shipments with batch scanning

Retail

  • Price checking with product barcodes
  • Inventory management
  • Customer loyalty card scanning

Event Management

  • Ticket validation with QR codes
  • Attendee check-in
  • Access control

Healthcare

  • Patient wristband scanning
  • Medication verification
  • Sample tracking

Getting started

Add the Genius Scan SDK as a dependency to your project by following the section Integrating the framework from the Getting Started guide.

Implementation

Basic Usage

import GSSDK

// Configure the readable code flow
let configuration = GSKReadableCodeFlowConfiguration()
configuration.isBatchModeEnabled = false
configuration.supportedCodeTypes = [.qr, .ean13, .code128]

// Optional: Customize UI colors using hex strings
configuration.highlightColor = .red
configuration.menuColor = .blue

// Start the flow
let readableCodeFlow = GSKReadableCodeFlow(configuration: configuration)

do {
    let result = try await readableCodeFlow.resultByStarting(fromViewController: self)

    // Process detected codes
    for code in result.readableCodes {
        print("Detected \(code.type): \(code.value)")
    }
} catch {
    // Handle errors (e.g., user cancellation, camera permission denied)
    print("Error: \(error)")
}
import com.geniusscansdk.readablecodeflow.*
import com.geniusscansdk.structureddata.ReadableCode

// Create configuration
val configuration = ReadableCodeConfiguration(
    isBatchModeEnabled = false,
    supportedCodeTypes = setOf(
        ReadableCode.Type.QR,
        ReadableCode.Type.EAN13,
        ReadableCode.Type.CODE128
    ),
    highlightColor = Color.red
)

// Register for result
val readableCodeLauncher = registerForActivityResult(
    ReadableCodeFlow.createContract()
) { result ->
    when (result) {
        is ReadableCodeFlowResult.Success -> {
            // Process detected codes
            result.codes.forEach { code ->
                Log.d("Scanner", "Detected ${code.type}: ${code.value}")
            }
        }
        is ReadableCodeFlowResult.Cancelled -> {
            // User cancelled scanning
        }
        is ReadableCodeFlowResult.Error -> {
            // Handle error
            Log.e("Scanner", "Error: ${result.message}")
        }
    }
}

// Launch the scanner
readableCodeLauncher.launch(configuration)
// Configure the scanner
const configuration = {
    isBatchModeEnabled: false,
    supportedCodeTypes: ['qr', 'ean13', 'code128'],
    highlightColor: '#ff0000',
    menuColor: '#0000ff'
};

// Start scanning
cordova.plugins.GeniusScan.scanReadableCodesWithConfiguration(
    configuration,
    function(result) {
        // Success callback
        result.readableCodes.forEach(code => {
            console.log(`Detected ${code.type}: ${code.value}`);
        });
    },
    function(error) {
        // Error callback
        console.error('Scanning failed:', error);
    }
);
import GeniusScan from '@thegrizzlylabs/react-native-genius-scan';

try {
    const result = await GeniusScan.scanReadableCodesWithConfiguration({
        isBatchModeEnabled: false,
        supportedCodeTypes: ['qr', 'ean13', 'code128'],
        highlightColor: '#ff0000',
        menuColor: '#0000ff'
    });

    // Process detected codes
    result.readableCodes.forEach(code => {
        console.log(`Detected ${code.type}: ${code.value}`);
    });
} catch (error) {
    console.error('Scanning error:', error);
}
import 'package:flutter_genius_scan/flutter_genius_scan.dart';

try {
    final result = await FlutterGeniusScan.scanReadableCodesWithConfiguration({
        'isBatchModeEnabled': false,
        'supportedCodeTypes': ['qr', 'ean13', 'code128'],
        'highlightColor': '#ff0000',
        'menuColor': '#0000ff'
    });

    for (var code in result['readableCodes']) {
        print('Detected ${code['type']}: ${code['value']}');
    }
} catch (e) {
    print('Scanning failed: $e');
}

Batch Mode

Batch mode allows scanning multiple unique codes in a single session:

let configuration = GSKReadableCodeFlowConfiguration()
configuration.isBatchModeEnabled = true
configuration.supportedCodeTypes = [.qr, .dataMatrix]

let readableCodeFlow = GSKReadableCodeFlow(configuration: configuration)
let result = try await readableCodeFlow.resultByStarting(fromViewController: self)

// Result contains all unique codes scanned during the session
print("Scanned \(result.readableCodes.count) unique codes")
val configuration = ReadableCodeConfiguration(
    isBatchModeEnabled = true,
    supportedCodeTypes = ReadableCode.Type.entries.toSet() // All types
)

readableCodeLauncher.launch(configuration)
const configuration = {
    isBatchModeEnabled: true,
    supportedCodeTypes: ['qr', 'dataMatrix', 'pdf417']
};

cordova.plugins.GeniusScan.scanReadableCodesWithConfiguration(
    configuration,
    function(result) {
        console.log(`Scanned ${result.readableCodes.length} unique codes`);
        result.readableCodes.forEach(code => {
            console.log(`${code.type}: ${code.value}`);
        });
    },
    function(error) {
        console.error('Scanning failed:', error);
    }
);
import GeniusScan from '@thegrizzlylabs/react-native-genius-scan';

try {
    const result = await GeniusScan.scanReadableCodesWithConfiguration({
        isBatchModeEnabled: true,
        supportedCodeTypes: ['qr', 'dataMatrix', 'pdf417']
    });

    console.log(`Scanned ${result.readableCodes.length} codes`);
    result.readableCodes.forEach(code => {
        console.log(`${code.type}: ${code.value}`);
    });
} catch (error) {
    console.error('Scanning error:', error);
}
import 'package:flutter_genius_scan/flutter_genius_scan.dart';

try {
    final result = await FlutterGeniusScan.scanReadableCodesWithConfiguration({
        'isBatchModeEnabled': true,
        'supportedCodeTypes': ['qr', 'dataMatrix', 'pdf417']
    });

    print('Scanned ${result['readableCodes'].length} unique codes');
    for (var code in result['readableCodes']) {
        print('${code['type']}: ${code['value']}');
    }
} catch (e) {
    print('Scanning failed: $e');
}

Configuration Options

Common Parameters

Parameter Type Description Default
isBatchModeEnabled Boolean Enable batch mode for scanning multiple codes false
supportedCodeTypes Array/Set Specific code types to detect All types
highlightColor Color Color for the detection overlay green
menuColor Color Color for interface elements (tint color) #000000

User Experience

Standard Mode

  1. Camera opens with real-time preview
  2. Point camera at readable code
  3. Green overlay highlights detected code
  4. Scanner automatically returns result

Batch Mode

  1. Camera opens with batch mode UI
  2. Scan multiple codes - each detected code is added to the list
  3. Duplicates are automatically filtered
  4. Tap “Done” to return all scanned codes

Best Practices

Performance Optimization

Specify Code Types

Only enable the code types you need to improve detection speed

   configuration.supportedCodeTypes = [.qr, .ean13] // Don't use all types
   configuration.supportedCodeTypes = setOf(
       ReadableCode.Type.QR,
       ReadableCode.Type.EAN13
   ) // Don't use all types
   const configuration = {
       supportedCodeTypes: ['qr', 'ean13'] // Don't use all types
   };
   const configuration = {
       supportedCodeTypes: ['qr', 'ean13'] // Don't use all types
   };
   final configuration = {
       'supportedCodeTypes': ['qr', 'ean13'] // Don't use all types
   };

Lighting Conditions

The scanner works best with adequate lighting. Consider enabling torch control for low-light environments.

Camera Distance

Maintain appropriate distance from codes - too close may cause focus issues, too far may prevent detection.

Error Handling

Always implement proper error handling for common scenarios:

do {
    let result = try await readableCodeFlow.resultByStarting(fromViewController: self)
    // Process result
} catch GSKReadableCodeFlowError.cancelled {
    // User cancelled - no action needed
} catch {
    // Handle other errors
}
when (result) {
    is ReadableCodeFlowResult.Success -> {
        // Process detected codes
    }
    is ReadableCodeFlowResult.Cancelled -> {
        // User cancelled - no action needed
    }
    is ReadableCodeFlowResult.Error -> {
        when (result.type) {
            ErrorType.PERMISSION_DENIED -> {
                // Show permission request UI
            }
            else -> {
                // Handle other errors
            }
        }
    }
}
cordova.plugins.GeniusScan.scanReadableCodesWithConfiguration(
    configuration,
    function(result) {
        // Success - process codes
    },
    function(error) {
        if (error.code === 'USER_CANCELLED') {
            // User cancelled - no action needed
        } else if (error.code === 'PERMISSION_DENIED') {
            // Show permission request UI
            alert('Camera permission is required to scan codes');
        } else {
            // Handle other errors
            console.error('Scanning error:', error.message);
        }
    }
);
try {
    const result = await GeniusScan.scanReadableCodesWithConfiguration(configuration);
    // Process result
} catch (error) {
    if (error.code === 'USER_CANCELLED') {
        // User cancelled - no action needed
    } else if (error.code === 'PERMISSION_DENIED') {
        // Show permission request UI
        Alert.alert(
            'Permission Required',
            'Camera permission is required to scan codes',
            [{ text: 'OK', onPress: () => Linking.openSettings() }]
        );
    } else {
        // Handle other errors
        Alert.alert('Scanning Error', error.message);
    }
}
try {
    final result = await FlutterGeniusScan.scanReadableCodesWithConfiguration(configuration);
    // Process result
} on PlatformException catch (e) {
    if (e.code == 'USER_CANCELLED') {
        // User cancelled - no action needed
    } else if (e.code == 'PERMISSION_DENIED') {
        // Show permission request UI
        showDialog(
            context: context,
            builder: (context) => AlertDialog(
                title: Text('Permission Required'),
                content: Text('Camera permission is required to scan codes'),
                actions: [
                    TextButton(
                        onPressed: () => openAppSettings(),
                        child: Text('Open Settings')
                    )
                ]
            )
        );
    } else {
        // Handle other errors
        print('Scanning error: ${e.message}');
    }
}

Troubleshooting

Common Issues

  1. Codes Not Detected
    • Ensure code type is included in supportedCodeTypes
    • Check lighting conditions
    • Verify camera focus distance
  2. ML Kit Initialization (Android)
    • Ensure Google Play Services is up to date
    • Check device has sufficient storage
    • Verify network connectivity for initial model download
  3. Performance Issues
    • Reduce number of supported code types
    • Ensure adequate device specifications
    • Close other camera-using apps

Supported Code Types

The following readable code formats are supported:

  • 1D codes: Code 128, Code 39, Code 93, EAN-13, EAN-8, UPC-A, UPC-E, ITF, Codabar (iOS 15+), MSI Plessey (iOS 17+)
  • 2D codes: QR Code, Data Matrix, PDF417, Aztec, Micro PDF417 (iOS 15+), Micro QR (iOS 15+)
  • GS1 Formats: GS1 DataBar (iOS 15+)

Platform Requirements

  • iOS: iOS 13.0+
  • Android: API 21+ with Google Play Services

Products

Industries

Case Studies

Integration

Company

© 2025 The Grizzly Labs. All rights reserved.