Limit DataScannerViewController text recognition | Swift/Xcode/VisionKit

345 Views Asked by At

I'm attempting to make the DataScannerViewController (VisionKit) only recognize VIN numbers. Currently, when I hold the camera up to a data plate, it reads all kinds of text, so I can't just grab the VIN number. I would like for the camera to ONLY recognize barcodes (code 39) and VIN numbers (so it doesn't pick up everything else). How could I accomplish this?

@available(iOS 16.0, *)
extension ScannerViewController: DataScannerViewControllerDelegate {
    func dataScanner(
        _ dataScanner: DataScannerViewController,
        didAdd addedItems: [RecognizedItem],
        allItems: [RecognizedItem]
    ) {
        // code
    }
    
    func dataScanner(
        _ dataScanner: DataScannerViewController,
        didUpdate updatedItems: [RecognizedItem],
        allItems: [RecognizedItem]
    ) {
        // code
    }
    
    func dataScanner(
        _ dataScanner: DataScannerViewController,
        didRemove removedItems: [RecognizedItem],
        allItems: [RecognizedItem]
    ) {
        // code
    }
    
    func dataScanner(
        _ dataScanner: DataScannerViewController,
        didTapOn item: RecognizedItem
    ) {
        // get the scanned string
        switch item {
        case let .text(text):
            let recognizedText = text.transcript
            print("recognizedText: \(recognizedText)")
            // Add VIN validation for text
            if isValidVIN(recognizedText) {
                delegate?.scannerViewController(self, didScanString: recognizedText)
            } else {
                print("not a valid VIN")
            }
        case let .barcode(barcode):
            let recognizedBarcode = barcode.payloadStringValue ?? ""
            print("recognizedBarcode: \(recognizedBarcode)")
            // Add VIN validation for barcodes
            if isValidVIN(recognizedBarcode) {
                delegate?.scannerViewController(self, didScanString: recognizedBarcode)
            } else {
                print("not a valid VIN barcode")
            }
        @unknown default: break
        }
    }
    
    // Add VIN validation function
    func isValidVIN(_ vin: String) -> Bool {
        let vinRegex = "^[A-HJ-NPR-Z0-9]{17}$"
        let vinPredicate = NSPredicate(format:"SELF MATCHES %@", vinRegex)
        return vinPredicate.evaluate(with: vin)
    }
}

@available(iOS 16.0, *)
extension DataScannerViewController {
    static func makeDatascanner(delegate: DataScannerViewControllerDelegate) -> DataScannerViewController {
        let scanner = DataScannerViewController(
            recognizedDataTypes: [
                // restrict the types here
                .barcode(symbologies: [
                    .code39
                ]),
                .text(languages: ["en"])
            ],
            isGuidanceEnabled: true,
            isHighlightingEnabled: true
        )

        scanner.delegate = delegate
        return scanner
    }
}
0

There are 0 best solutions below