You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让VisionKit的DataScannerViewController仅识别VIN码与Code39条码?

实现VisionKit仅识别VIN码和Code39条码

要让DataScannerViewController只识别VIN码和Code39条码,需要从扫描类型配置和结果过滤两方面入手,同时优化用户体验避免无效内容干扰:

1. 配置扫描类型

首先限制扫描器仅识别Code39条码和英文文本(VIN码由大写字母和数字组成):

@available(iOS 16.0, *)
extension DataScannerViewController {
    static func makeDatascanner(delegate: DataScannerViewControllerDelegate) -> DataScannerViewController {
        let scanner = DataScannerViewController(
            recognizedDataTypes: [
                .barcode(symbologies: [.code39]), // 仅启用Code39条码识别
                .text(languages: ["en"]) // 仅识别英文文本(适配VIN码字符集)
            ],
            isGuidanceEnabled: true,
            isHighlightingEnabled: false // 关闭默认高亮,后续自定义有效VIN的高亮
        )
        scanner.delegate = delegate
        return scanner
    }
}

2. 过滤无效扫描结果

在代理方法中,只处理符合VIN格式的内容(17位,不含I/O/Q),并忽略其他所有识别结果:

@available(iOS 16.0, *)
extension ScannerViewController: DataScannerViewControllerDelegate {
    // 处理新增识别项
    func dataScanner(
        _ dataScanner: DataScannerViewController,
        didAdd addedItems: [RecognizedItem],
        allItems: [RecognizedItem]
    ) {
        processValidVINItems(from: addedItems)
    }
    
    // 处理更新的识别项
    func dataScanner(
        _ dataScanner: DataScannerViewController,
        didUpdate updatedItems: [RecognizedItem],
        allItems: [RecognizedItem]
    ) {
        processValidVINItems(from: updatedItems)
    }
    
    // 处理移除的识别项(清理对应高亮视图)
    func dataScanner(
        _ dataScanner: DataScannerViewController,
        didRemove removedItems: [RecognizedItem],
        allItems: [RecognizedItem]
    ) {
        // 可在此移除对应无效项的自定义高亮视图
    }
    
    // 处理点击事件
    func dataScanner(
        _ dataScanner: DataScannerViewController,
        didTapOn item: RecognizedItem
    ) {
        switch item {
        case let .text(text) where isValidVIN(text.transcript):
            delegate?.scannerViewController(self, didScanString: text.transcript)
        case let .barcode(barcode) where isValidVIN(barcode.payloadStringValue ?? ""):
            delegate?.scannerViewController(self, didScanString: barcode.payloadStringValue ?? "")
        default:
            break // 直接忽略无效点击
        }
    }
    
    // 过滤并处理有效VIN项(添加自定义高亮)
    private func processValidVINItems(from items: [RecognizedItem]) {
        let validVINs = items.filter { item in
            switch item {
            case let .text(text):
                return isValidVIN(text.transcript)
            case let .barcode(barcode):
                return isValidVIN(barcode.payloadStringValue ?? "")
            default:
                return false
            }
        }
        
        // 为有效VIN绘制自定义高亮框
        validVINs.forEach { item in
            let frame: CGRect
            switch item {
            case let .text(text): frame = text.boundingBox
            case let .barcode(barcode): frame = barcode.boundingBox
            default: return
            }
            
            let overlay = UIView()
            overlay.layer.borderColor = UIColor.systemGreen.cgColor
            overlay.layer.borderWidth = 2
            overlay.frame = frame
            dataScanner.view.addSubview(overlay)
        }
    }
    
    // VIN格式验证(符合ISO标准:17位,排除I/O/Q)
    private 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)
    }
}

关键优化点

  • 关闭默认高亮:避免无关文本被高亮,仅对有效VIN绘制自定义高亮,减少用户干扰。
  • 提前过滤结果:在didAdd/didUpdate阶段就过滤无效内容,减少后续处理逻辑。
  • 严格格式校验:用正则表达式确保只有符合标准的17位VIN码被识别。

内容的提问来源于stack exchange,提问作者Christian W

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 17:17:28