/ BalanceKit / BarcodeScannerView.swift
BarcodeScannerView.swift
 1  //
 2  //  BarcodeScannerView.swift
 3  //  BalanceKit
 4  //
 5  //  Created by Gemini on 13.07.25.
 6  //
 7  
 8  import SwiftUI
 9  import VisionKit
10  
11  // This view will host the barcode scanner functionality.
12  // It uses a UIViewControllerRepresentable to wrap the DataScannerViewController from VisionKit.
13  
14  struct BarcodeScannerView: UIViewControllerRepresentable {
15      
16      @Binding var scannedCode: String?
17      @Environment(\.dismiss) var dismiss
18      
19      func makeUIViewController(context: Context) -> DataScannerViewController {
20          let viewController = DataScannerViewController(
21              recognizedDataTypes: [.barcode()], // We are only interested in barcodes
22              qualityLevel: .balanced,
23              isHighlightingEnabled: true
24          )
25          
26          viewController.delegate = context.coordinator
27          return viewController
28      }
29      
30      func updateUIViewController(_ uiViewController: DataScannerViewController, context: Context) {
31          // Try to start scanning when the view appears.
32          try? uiViewController.startScanning()
33      }
34      
35      func makeCoordinator() -> Coordinator {
36          Coordinator(self)
37      }
38      
39      // MARK: - Coordinator
40      // The coordinator will act as the delegate for the DataScannerViewController.
41      class Coordinator: NSObject, DataScannerViewControllerDelegate {
42          var parent: BarcodeScannerView
43          
44          init(_ parent: BarcodeScannerView) {
45              self.parent = parent
46          }
47          
48          func dataScanner(_ dataScanner: DataScannerViewController, didTapOn item: RecognizedItem) {
49              handle(item: item)
50          }
51          
52          func dataScanner(_ dataScanner: DataScannerViewController, didAdd addedItems: [RecognizedItem], allItems: [RecognizedItem]) {
53              guard let item = addedItems.first else { return }
54              handle(item: item)
55          }
56          
57          private func handle(item: RecognizedItem) {
58              switch item {
59              case .barcode(let barcode):
60                  if let payload = barcode.payloadStringValue {
61                      parent.scannedCode = payload
62                      // Stop scanning and dismiss the view once a code is found.
63                      parent.dismiss()
64                  }
65              default:
66                  break
67              }
68          }
69      }
70  }