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

已用Swift+AVFoundation实现条码阅读器,请求新增Code39Mod10与Codabar支持

Adding Code39Mod10 and Codabar Support to Your AVFoundation Barcode Reader

Hey there! Let’s walk through how to add support for these two barcode types to your existing Swift/AVFoundation reader—they’re totally manageable with a mix of native AVFoundation features and a little custom logic.

1. Adding Codabar Support

Good news: AVFoundation actually has built-in support for Codabar that you might have overlooked. Just add the AVMetadataObjectTypeCodabarCode constant to your supportedCodeTypes array, right alongside your existing types:

let supportedCodeTypes = [
    AVMetadataObjectTypeUPCECode,
    AVMetadataObjectTypeCode39Code,
    AVMetadataObjectTypeCode39Mod43Code,
    AVMetadataObjectTypeCode93Code,
    AVMetadataObjectTypeCode128Code,
    AVMetadataObjectTypeEAN8Code,
    AVMetadataObjectTypeEAN13Code,
    AVMetadataObjectTypeAztecCode,
    AVMetadataObjectTypePDF417Code,
    AVMetadataObjectTypeQRCode,
    // Add Codabar here
    AVMetadataObjectTypeCodabarCode
    // ... any other remaining types you had
]

Once added, AVFoundation will detect Codabar barcodes automatically, just like all the types you’re already handling. No extra work needed here!

2. Adding Code39Mod10 Support

Code39Mod10 is a variant of standard Code39 that includes a Mod10 check digit for validation. AVFoundation doesn’t have a dedicated metadata type for it, but it will still scan Code39Mod10 barcodes as regular Code39. To fully support it, you’ll need to add custom logic to validate the check digit after scanning.

Step 1: Keep AVMetadataObjectTypeCode39Code in your supported list

Make sure this constant stays in your supportedCodeTypes—it’s how AVFoundation will pick up the Code39Mod10 barcode in the first place.

Step 2: Build a helper function to validate the Mod10 check digit

Create a function to verify that the scanned Code39 string has a valid Mod10 check digit:

func isCode39Mod10Valid(_ code: String) -> Bool {
    // Code39Mod10 uses the last character as the check digit
    guard code.count >= 2 else { return false }
    
    let payload = String(code.dropLast())
    guard let checkDigit = code.last else { return false }
    
    // Map Code39 characters to their numerical values
    let characterValues: [Character: Int] = [
        "0": 0, "1": 1, "2": 2, "3": 3, "4": 4,
        "5": 5, "6": 6, "7": 7, "8": 8, "9": 9,
        "A": 10, "B": 11, "C": 12, "D": 13, "E": 14,
        "F": 15, "G": 16, "H": 17, "I": 18, "J": 19,
        "K": 20, "L": 21, "M": 22, "N": 23, "O": 24,
        "P": 25, "Q": 26, "R": 27, "S": 28, "T": 29,
        "U": 30, "V": 31, "W": 32, "X": 33, "Y": 34,
        "Z": 35, "-": 36, ".": 37, "$": 38, "/": 39,
        "+": 40, "%": 41
    ]
    
    // Calculate sum of all payload character values
    var sum = 0
    for char in payload {
        guard let value = characterValues[char] else { return false }
        sum += value
    }
    
    // Compute the expected check digit and compare to the scanned one
    let expectedCheckDigitValue = sum % 10
    guard let actualCheckDigitValue = characterValues[checkDigit],
          actualCheckDigitValue == expectedCheckDigitValue else {
        return false
    }
    
    return true
}

Step 3: Use the validator in your detection callback

When AVFoundation returns a scanned Code39 barcode, run it through the validator to distinguish valid Code39Mod10 barcodes from standard Code39:

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
    guard let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
          let scannedValue = metadataObject.stringValue else {
        return
    }
    
    switch metadataObject.type {
    case AVMetadataObjectTypeCode39Code:
        if isCode39Mod10Valid(scannedValue) {
            // Handle valid Code39Mod10 barcode
            print("Valid Code39Mod10 detected: \(scannedValue)")
        } else {
            // Handle standard Code39 or invalid Code39Mod10
            print("Standard Code39 or invalid Code39Mod10: \(scannedValue)")
        }
    // Handle your other barcode types here...
    default:
        print("Scanned \(metadataObject.type.rawValue): \(scannedValue)")
    }
}

Quick Recap

  • Codabar is a no-brainer—just add the native AVFoundation constant to your supported list.
  • Code39Mod10 needs a little extra work: AVFoundation scans it as standard Code39, so you’ll use your custom validator to confirm the check digit is valid.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 02:27:35