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.
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 |
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 |
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 -> {
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}');
}
}
supportedCodeTypes
The following readable code formats are supported:
© 2025 The Grizzly Labs. All rights reserved.