CodeScanner Documentation

repository·main·Indexed 22 days ago

https://github.com/twostraws/codescanner

A SwiftUI framework for simplifying QR code and barcode scanning. It provides the CodeScannerView component with support for various scan modes, simulated data for testing, and customizable options for viewfinders, torch control, and haptic feedback.

Tokens
1.2K
Snippets
3
Records
5
Agent score
29%

What's inside CodeScanner

  1. Basic usage of CodeScannerView

    main

    To use CodeScannerView, initialize it with an array of codeTypes to scan for and a completion closure. The closure receives a Result<ScanResult, ScanError>.

    Important Setup: You must add the Privacy - Camera Usage Description key to your Info.plist file to request camera access from the user.

    CodeScannerView(codeTypes: [.qr], simulatedData: "Paul Hudson") { response in                    
        switch response {
        case .success(let result):
            print("Found code: \(result.string)")
        case .failure(let error):
            print(error.localizedDescription)
        }
    }
  2. Configure CodeScannerView customization options

    main

    You can customize the behavior and appearance of CodeScannerView using the following parameters in its initializer:

    • scanMode: Determines scanning behavior. Options are .once (default), .oncePerCode (scans many but only triggers once per unique code), and .continuous (keeps finding codes until dismissed).
    • scanInterval: The time in seconds between individual scans when using .continuous mode.
    • showViewfinder: A Boolean determining whether to show a viewfinder box over the UI (default: false).
    • simulatedData: A string used to provide test data in the Simulator (default: "").
    • shouldVibrateOnSuccess: A Boolean determining whether the device vibrates when a code is found (default: true).
    • videoCaptureDevice: Allows selecting a specific AVCaptureDevice (e.g., for better focus on small codes).
    • isTorchOn: A Boolean to turn the device's flashlight on or off (default: false).

    To add custom UI elements like a Cancel button, wrap the CodeScannerView in a NavigationView and use the .toolbar() modifier.

  3. Scan small QR codes with optimized focus

    main

    On devices with dual or triple cameras, scanning small QR codes may require adjusting the focus distance. You can use AVCaptureDevice.zoomedCameraForQRCode(withMinimumCodeSize:) to select a more suitable camera and zoom factor.

    CodeScannerView(codeTypes: [.qr], videoCaptureDevice: AVCaptureDevice.zoomedCameraForQRCode(withMinimumCodeSize: 20)) { response in                    
        switch response {
        case .success(let result):
            print("Found code: \(result.string)")
        case .failure(let error):
            print(error.localizedDescription)
        }
    }
  4. Present CodeScannerView as a sheet

    main

    A common pattern is to present the scanner as a SwiftUI sheet. You can update your view state with the scanned result and dismiss the sheet within the completion closure.

    struct QRCodeScannerExampleView: View {
        @State private var isPresentingScanner = false
        @State private var scannedCode: String?
    
        var body: some View {
            VStack(spacing: 10) {
                if let code = scannedCode {
                    NavigationLink("Next page", destination: NextView(scannedCode: code), isActive: .constant(true)).hidden()
                }
    
                Button("Scan Code") {
                    isPresentingScanner = true
                }
    
                Text("Scan a QR code to begin")
            }
            .sheet(isPresented: $isPresentingScanner) {
                CodeScannerView(codeTypes: [.qr]) { response in
                    if case let .success(result) = response {
                        scannedCode = result.string
                        isPresentingScanner = false
                    }
                }
            }
        }
    }
  5. Handle ScanError cases

    main

    When scanning fails, the completion closure returns a ScanError. The possible error cases are:

    • badInput: The camera cannot be accessed.
    • badOutput: The camera is not capable of detecting codes.
    • initError: Initialization failed.