The Genius Scan SDK includes a dedicated barcode scanning flow 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.
The Genius Scan SDK also offers document-centric barcode extraction, but the present tutorial focuses on continuous, real-time scanning scenarios.
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 |
The Genius Scan SDK barcode scanning flow has been designed to handle the needs of various industries where speed and accuracy are key.
Add the Genius Scan SDK as a dependency to your project by following the section Integrating the framework from the Getting Started guide.
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 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');
}
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 |
The Genius Scan SDK barcode scan flow offers two modes:
The standard mode is designed to let your users scan one barcode and immediately returns to let you process it.
The batch mode lets your users scan multiple barcodes and validate once they are done.
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
};
The scanner works best with adequate lighting. Consider enabling torch control for low-light environments.
Maintain appropriate distance from codes - too close may cause focus issues, too far may prevent detection.
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 -> {
// Handle errors
}
}
cordova.plugins.GeniusScan.scanReadableCodesWithConfiguration(
configuration,
function(result) {
// Success - process codes
},
function(error) {
if (error.code === 'E_SCAN_CANCELED' || error.code === 'com.thegrizzlylabs.gssdk.scanflow.ErrorDomain error 999') {
// User cancelled - no action needed
} else {
// Handle other errors,
alert('Scanning error: '+ error.message);
}
}
);
try {
const result = await GeniusScan.scanReadableCodesWithConfiguration(configuration);
// Process result
} catch (error) {
if (error.code === 'E_SCAN_CANCELED' || error.code === 'com.thegrizzlylabs.gssdk.scanflow.ErrorDomain error 999') {
// User cancelled - no action needed
} else {
// Handle other errors
Alert.alert('Scanning Error', error.message);
}
}
try {
final result = await FlutterGeniusScan.scanReadableCodesWithConfiguration(configuration);
// Process result
} on PlatformException catch (e) {
if (error.code == 'E_SCAN_CANCELED' || error.code == 'com.thegrizzlylabs.gssdk.scanflow.ErrorDomain error 999') {
// User cancelled - no action needed
} else {
// Handle other errors
print('Scanning error: ${e.message}');
}
}
supportedCodeTypes
The following readable code formats are supported:
© 2025 The Grizzly Labs. All rights reserved.