tauri-plugin-barcode-scanner-continuous 0.1.0

Fork of tauri-plugin-barcode-scanner with on-device fixes enabling a stable continuous scan loop on iOS and Android.
docs.rs failed to build tauri-plugin-barcode-scanner-continuous-0.1.0
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

tauri-plugin-barcode-scanner-continuous

Fork of @tauri-apps/plugin-barcode-scanner with on-device fixes that enable a stable continuous scan loop on iOS and Android.

The API surface is the same as the upstream plugin (scan, cancel, checkPermissions, requestPermissions, openAppSettings), so it is a near drop-in replacement when the consumer wants to keep a scanner overlay open across many detections — a common pattern in Point-of-Sale checkout flows.

Platform Supported
iOS
Android
macOS / Windows / Linux

Why this fork

tauri-plugin-barcode-scanner 2.4.4 (the latest release on crates.io at the time of this fork) had two unresolved on-device bugs that prevented a reliable continuous scanning UX:

  1. iOS app crash when cancel() is called while a scan is live. Upstream's cancel() runs on the IPC thread, so tearing the capture session down from JS races destroy() on the main thread. See tauri-apps/plugins-workspace#3081.
  2. iOS taps stop working after a scan. dismantleCamera() removed the preview layer but left the UIView in the superview hierarchy, intercepting touches. See PR #3107 / PR #2440.

Both are fixed in unreleased upstream work, but as of 2.4.4 they were not in any published crate.

This fork carries those patches plus a small additive feature so it can live alongside the upstream plugin in a project without conflicting with its ACL / Tauri plugin namespace.

What is different from upstream

iOS (Swift)

  • cancel() wraps its body in DispatchQueue.main.async { … }. Fixes the crash when the close button is pressed while scan() is still running.
  • dismantleCamera() now calls self.cameraView.removeFromSuperview(). Fixes the unresponsive-after-scan bug.
  • scan() accepts an optional overlayInsetBottom argument (points). When running in non-windowed mode on iOS, this leaves a transparent strip at the bottom of the camera preview so apps can keep their own UI (e.g. a cart bottom-sheet) visible.

Renamed identifiers (to avoid collision with upstream)

Thing Upstream This fork
Crate name tauri-plugin-barcode-scanner tauri-plugin-barcode-scanner-continuous
Rust lib tauri_plugin_barcode_scanner tauri_plugin_barcode_scanner_continuous
Tauri plugin name barcode-scanner barcode-scanner-continuous
ACL prefix barcode-scanner:* barcode-scanner-continuous:*
iOS @_cdecl init init_plugin_barcode_scanner init_plugin_barcode_scanner_continuous
Android Java package app.tauri.barcodescanner app.tauri.barcodescannercontinuous

Installing both this fork and the upstream plugin in the same app is supported.

Install

Rust (src-tauri/Cargo.toml)

[target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies]
tauri-plugin-barcode-scanner-continuous = "0.1"

JavaScript

npm install @riczescaran/tauri-plugin-barcode-scanner-continuous

Register the plugin (src-tauri/src/lib.rs)

#[cfg(any(target_os = "android", target_os = "ios"))]
let builder = builder.plugin(tauri_plugin_barcode_scanner_continuous::init());

Allow the commands (src-tauri/capabilities/mobile.json)

{
  "permissions": ["barcode-scanner-continuous:default"]
}

Usage

import {
  scan,
  cancel,
  Format,
} from '@riczescaran/tauri-plugin-barcode-scanner-continuous'

// Continuous loop — the caller drives the loop; the plugin resolves one
// scan() call per detection and internally tears down the capture session
// in a way that is safe to re-arm on the next iteration.
async function runScanLoop() {
  while (shouldKeepScanning()) {
    try {
      const { content } = await scan({
        windowed: true,
        formats: [Format.EAN13, Format.EAN8, Format.QRCode],
      })
      addToCart(content)
    } catch (e) {
      // cancel() rejects the in-flight scan() with "cancelled" — this is
      // the normal exit from the loop.
      if (String(e).match(/cancel/i)) break
      throw e
    }
  }
}

// Close the overlay:
await cancel()

License

Apache-2.0 OR MIT. Derivative work of the upstream @tauri-apps/plugin-barcode-scanner, Copyright © 2019-Present — The Tauri Programme within The Commons Conservancy.

See LICENSE_APACHE-2.0 and LICENSE_MIT.