Pregunta

Scanning this (https://www.barcoderobot.com/static/bcgen/01026/478064310081_3b120.jpg?preview=True) barcode we should obtain the following result: 47806431008

Using the iOS7 api to read the barcodes, I have the following result: 047806431008

Any ideias how to deal with this?

part of the code:

CGRect highlightViewRect = CGRectZero;
AVMetadataMachineReadableCodeObject *barCodeObject;
NSString *detectionString = nil;
NSArray *barCodeTypes = @[AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode39Mod43Code,
                          AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode128Code,
                          AVMetadataObjectTypePDF417Code, AVMetadataObjectTypeQRCode, AVMetadataObjectTypeAztecCode];

for (AVMetadataObject *metadata in metadataObjects) {
    for (NSString *type in barCodeTypes) {
        if ([metadata.type isEqualToString:type])
        {
            barCodeObject = (AVMetadataMachineReadableCodeObject *)[_prevLayer transformedMetadataObjectForMetadataObject:(AVMetadataMachineReadableCodeObject *)metadata];
            highlightViewRect = barCodeObject.bounds;
            detectionString = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
            break;
        }
    }

    if (detectionString != nil)
    {
        [_session stopRunning];
        [self scanResult:detectionString];
        break;
    }
¿Fue útil?

Solución

I found the problem. Apple just convert every UPC-A barcode to EAN13 just by adding a leading zero.

The solution is to verify if the barcode is EAN13 and if the string result have a leading zero is safe to remove it and obtain a UPC-A barcode.

if(detectionString!=nil){
    if([metadata.type isEqualToString:AVMetadataObjectTypeEAN13Code]){
        if ([detectionString hasPrefix:@"0"] && [detectionString length] > 1)
            detectionString = [detectionString substringFromIndex:1];
    }
}

Link to Apple technical note: https://developer.apple.com/library/content/technotes/tn2325/_index.html#//apple_ref/doc/uid/DTS40013824-CH1-IS_UPC_A_SUPPORTED_

More information in: http://www-01.ibm.com/support/docview.wss?uid=pos1R1002813

According to the Uniform Code Council, an EAN-13 barcode that begins with a zero is, by definition, a 12-digit UPC-A barcode. To follow this rule, when a scanner device reads an EAN-13 barcode beginning with a zero, it drops the leading 0, truncates the barcode to 12 digits and appends the UPC-A (instead of EAN-13) indicator to the label, before passing the label to the Operating System. Therefore, the Operating System has no way to recognize that this UPC-A label that was passed to it by the scanner device was initially an EAN-13 label beginning with a zero.

Otros consejos

In case anyone interested in for the swift version.

Swift 3.1:

guard let barcodeReadable = barcodeData as? AVMetadataMachineReadableCodeObject else {
    return
}

guard var barcode = barcodeReadable.stringValue else {
    return
}

if barcodeReadable.type == AVMetadataObjectTypeEAN13Code && barcode.hasPrefix("0"){
    let index = barcode.index(barcode.startIndex, offsetBy: 1)
    barcode = barcode.substring(from: index)
}

As Sandro and Gunhan wrote:

The solution is to verify if the barcode is EAN13.

This code will work for Swift 4.2 version:

if let metadataObject = metadataObjects.first {
        guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
        guard var stringValue = readableObject.stringValue else { return }

        if readableObject.type == AVMetadataObject.ObjectType.ean13 && stringValue.hasPrefix("0"){
            let index = stringValue.index(stringValue.startIndex, offsetBy: 1)
            stringValue = String(stringValue[index...])

        }

Verified solution in swift version 5.0 with better way to drop zero string.

guard !metadataObjects.isEmpty else { return }

guard let metadataObj = metadataObjects[0] as? AVMetadataMachineReadableCodeObject,
  var barcode = metadataObj.stringValue,
  metadata.contains(metadataObj.type)
  else { return }

var type = metadataObj.type.rawValue

if metadataObj.type == AVMetadataObject.ObjectType.ean13 && barcode.hasPrefix("0") {
  barcode = String(barcode.dropFirst())
  type = AVMetadataObject.ObjectType.upca.rawValue
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top