diff --git a/plugin/README.md b/plugin/README.md index 5cffee9..b489e89 100644 --- a/plugin/README.md +++ b/plugin/README.md @@ -27,6 +27,21 @@ The barcode scanner uses the camera on the device. Ensure you configure the Priv Note: iOS supports all formats except `MAXICODE` and `UPC_EAN_EXTENSION` - using them in `hint` will default to scanning any format. Also, Apple Vision does not distinguish between `UPC_A` and `EAN_13`, so specifying one of these in `hint` will allow to scan both. +#### Multi-format scanning with `hints` + +Pass `hints` instead of `hint` to restrict scanning to more than one specific format. The decoder is pre-filtered to that set, which is faster than scanning everything and avoids accepting unrelated barcodes that happen to be in frame. When `hints` is non-empty it takes precedence over `hint`, so callers should pass either `hint` (single format) or `hints` (multiple formats), not both: + +```ts +await CapacitorBarcodeScanner.scanBarcode({ + hints: [ + CapacitorBarcodeScannerTypeHint.EAN_13, + CapacitorBarcodeScannerTypeHint.CODE_128, + ], +}); +``` + +If `CapacitorBarcodeScannerTypeHintALLOption.ALL` appears anywhere in `hints` the scanner falls back to scan-all behavior. On iOS, when both `UPC_A` and `EAN_13` are present in `hints` the returned `format` defaults to `EAN_13` (Apple Vision cannot distinguish the two). + --- ## API @@ -90,7 +105,7 @@ to represent the hint for the type of barcode to be scanned. Defines the options for configuring a barcode scan. -{ hint: CapacitorBarcodeScannerTypeHint; scanInstructions?: string; scanButton?: boolean; scanText?: string; cameraDirection?: CapacitorBarcodeScannerCameraDirection; scanOrientation?: CapacitorBarcodeScannerScanOrientation; android?: { scanningLibrary?: CapacitorBarcodeScannerAndroidScanningLibrary; }; web?: { showCameraSelection?: boolean; scannerFPS?: number; }; } +{ hint?: CapacitorBarcodeScannerTypeHint; hints?: CapacitorBarcodeScannerTypeHint[]; scanInstructions?: string; scanButton?: boolean; scanText?: string; cameraDirection?: CapacitorBarcodeScannerCameraDirection; scanOrientation?: CapacitorBarcodeScannerScanOrientation; android?: { scanningLibrary?: CapacitorBarcodeScannerAndroidScanningLibrary; }; web?: { showCameraSelection?: boolean; scannerFPS?: number; }; } ### Enums diff --git a/plugin/android/src/main/java/com/capacitorjs/barcodescanner/OSBarcodePlugin.kt b/plugin/android/src/main/java/com/capacitorjs/barcodescanner/OSBarcodePlugin.kt index 5fc343c..1bf888a 100644 --- a/plugin/android/src/main/java/com/capacitorjs/barcodescanner/OSBarcodePlugin.kt +++ b/plugin/android/src/main/java/com/capacitorjs/barcodescanner/OSBarcodePlugin.kt @@ -33,6 +33,10 @@ class CapacitorBarcodeScannerPlugin : Plugin() { val hint: OSBARCScannerHint? = call.getInt("hint")?.let { OSBARCScannerHint.entries.getOrNull(it) } + val hints: List? = call.getArray("hints") + ?.toList() + ?.mapNotNull { OSBARCScannerHint.entries.getOrNull(it) } + ?.ifEmpty { null } val scanInstructions = call.getString("scanInstructions") val scanButton = call.getBoolean("scanButton", false) ?: false val scanText = call.getString("scanText", "") ?: "" @@ -47,7 +51,8 @@ class CapacitorBarcodeScannerPlugin : Plugin() { scanButton = scanButton, scanText = scanText, hint = hint, - androidScanningLibrary = androidScanningLibrary + androidScanningLibrary = androidScanningLibrary, + hints = hints ) val scanIntent = Intent(activity, OSBARCScannerActivity::class.java) diff --git a/plugin/ios/Sources/CapacitorBarcodeScannerPlugin/OSBARCScanParameters+Decodable.swift b/plugin/ios/Sources/CapacitorBarcodeScannerPlugin/OSBARCScanParameters+Decodable.swift index ddbe916..1e7985c 100644 --- a/plugin/ios/Sources/CapacitorBarcodeScannerPlugin/OSBARCScanParameters+Decodable.swift +++ b/plugin/ios/Sources/CapacitorBarcodeScannerPlugin/OSBARCScanParameters+Decodable.swift @@ -10,6 +10,7 @@ extension OSBARCScanParameters: Decodable { case cameraDirection case scanOrientation case hint + case hints } public init(from decoder: Decoder) throws { @@ -29,15 +30,19 @@ extension OSBARCScanParameters: Decodable { let scanOrientationInt = try container.decode(Int.self, forKey: .scanOrientation) let scanOrientation = OSBARCOrientationModel.map(value: scanOrientationInt) - let hintInt = try container.decode(Int.self, forKey: .hint) - let hint = OSBARCScannerHint(rawValue: hintInt) + let hintInt = try container.decodeIfPresent(Int.self, forKey: .hint) + let hint = hintInt.flatMap { OSBARCScannerHint(rawValue: $0) } + + let hintInts = try container.decodeIfPresent([Int].self, forKey: .hints) + let hints = hintInts?.compactMap { OSBARCScannerHint(rawValue: $0) } self.init( scanInstructions: scanInstructions, scanButtonText: scanButtonText, cameraDirection: cameraDirection, scanOrientation: scanOrientation, - hint: hint + hint: hint, + hints: hints ) } } diff --git a/plugin/src/definitions.ts b/plugin/src/definitions.ts index 91382ac..cef1972 100644 --- a/plugin/src/definitions.ts +++ b/plugin/src/definitions.ts @@ -62,7 +62,8 @@ export type CapacitorBarcodeScannerScanResult = { * Defines the options for configuring a barcode scan. */ export type CapacitorBarcodeScannerOptions = { - hint: CapacitorBarcodeScannerTypeHint; + hint?: CapacitorBarcodeScannerTypeHint; + hints?: CapacitorBarcodeScannerTypeHint[]; scanInstructions?: string; scanButton?: boolean; scanText?: string; diff --git a/plugin/src/web.ts b/plugin/src/web.ts index edfa2d6..1298985 100644 --- a/plugin/src/web.ts +++ b/plugin/src/web.ts @@ -114,6 +114,19 @@ export class CapacitorBarcodeScannerWeb "cap-os-barcode-scanner-container-dialog", )!.style.display = "block"; return new Promise((resolve, reject) => { + const ALL = 17; + const requestedHints = ( + options.hints?.length + ? options.hints + : options.hint !== undefined + ? [options.hint] + : [] + ) as number[]; + const resolvedTypeHints = + requestedHints.length === 0 || requestedHints.includes(ALL) + ? undefined + : requestedHints; + const param = { facingMode: options.cameraDirection === 1 ? "environment" : "user", hasScannerButton: false, @@ -129,7 +142,7 @@ export class CapacitorBarcodeScannerWeb showCameraSelection: options.web?.showCameraSelection ? options.web.showCameraSelection : false, - typeHint: options.hint === 17 ? undefined : options.hint, + typeHints: resolvedTypeHints, scannerFPS: options.web?.scannerFPS ? options.web.scannerFPS : 50, }; @@ -155,8 +168,7 @@ export class CapacitorBarcodeScannerWeb } (window as any).OSBarcodeWebScanner = new Html5Qrcode(scannerElement.id, { - formatsToSupport: - param.typeHint !== undefined ? [param.typeHint] : undefined, + formatsToSupport: param.typeHints, verbose: undefined, }); const Html5QrcodeConfig = {