Fix barcode scanner on iOS Safari
iOS WebKit does not provide a reliable native Barcode Detection API, and ZXing often failed due to strict camera constraints and video startup timing. - Install @undecaf/barcode-detector-polyfill (ZBar WASM) on Apple devices - Fall back through progressively looser getUserMedia constraints - Wait for video metadata/playback before decoding frames - Throttle native scans on iOS and tune ZXing retry intervals - Defer scanner startup until the modal video element is mounted Co-authored-by: Ned Halksworth <hello@nedhalksworth.com>
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { BarcodeDetectorPolyfill } from "@undecaf/barcode-detector-polyfill";
|
||||
|
||||
type WindowWithBarcodeDetector = Window & {
|
||||
BarcodeDetector?: typeof BarcodeDetectorPolyfill;
|
||||
};
|
||||
|
||||
let detectorReady: Promise<void> | null = null;
|
||||
|
||||
export function isAppleMobileDevice() {
|
||||
if (typeof navigator === "undefined") return false;
|
||||
const ua = navigator.userAgent;
|
||||
return /iPad|iPhone|iPod/i.test(ua) || (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1);
|
||||
}
|
||||
|
||||
export function ensureBarcodeDetector() {
|
||||
if (detectorReady) return detectorReady;
|
||||
|
||||
detectorReady = (async () => {
|
||||
const globalWindow = window as WindowWithBarcodeDetector;
|
||||
const shouldForcePolyfill = isAppleMobileDevice();
|
||||
|
||||
if (shouldForcePolyfill) {
|
||||
globalWindow.BarcodeDetector = BarcodeDetectorPolyfill;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await globalWindow.BarcodeDetector?.getSupportedFormats();
|
||||
} catch {
|
||||
globalWindow.BarcodeDetector = BarcodeDetectorPolyfill;
|
||||
}
|
||||
})();
|
||||
|
||||
return detectorReady;
|
||||
}
|
||||
Reference in New Issue
Block a user