Machina
Machina

Reputation: 242

Differentiate between UPC-E and EAN-8 in Swift

Regarding barcodes, UPC-E and EAN-8 have the same amount of digits. (8)

When I scan a barcode, I have to remove the check-digit. I have to remove it to match with the barcode in the database.

How can I differentiate between these two? With my other barcodes, I differentiate based on digit length and remove the last digit, but for these two I can't because they're both 8 digits and only 1 needs to have the check digits removed

Is there a way that I can differentiate based on the check-digit algorithm, or...

Upvotes: 5

Views: 3110

Answers (4)

Ethan Allen
Ethan Allen

Reputation: 14835

If you are using Apple's built-in iOS barcode scanner with the AVCaptureMetadataOutputObjectsDelegate delegate calls, you can determine the type scanned with this code:

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection)
{
    let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
    if metadataObj.type == .ean8 {
        // do stuff
    }
    else if metadataObj.type == .upce {
        // do stuff
    }
}

Once you know the barcode type you scanned, you can handle whether to use a check-digit verification or not.

Upvotes: 0

picciano
picciano

Reputation: 22701

I don't think you always can. EAN-8 and UPC-E have different checksum mechanisms. For UPC-E, you first expand to UPC-A, then compute the checksum. Fo EAN-8, you just use the first 7 digits. If the check digit is only valid for either EAN-8 or UPC-E, then you have got your answer. But if both match (I believe that can happen), then you can't determine whether it's EAN8 or UPCE based on the digits alone.

Upvotes: 5

Machina
Machina

Reputation: 242

Ended up doing a work-around.. If it didn't connect, then remove and try again. Thanks Kuba

if (barcodeLength == 13) {

        // EAN-13 \\

        // ********** Database Function ********** Database Function ********** \\


        // 1
        let urlString: String = "http://\(hostString):\(portString)/barcode.php?&password=\(passString)&db=\(dbString)&barNum=\(self.scannedBarcode)"
        let url: NSURL?  = NSURL(string: urlString)!
        let urlSession = NSURLSession.sharedSession()


        //2
        let jsonQuery = urlSession.dataTaskWithURL(url!, completionHandler: { data, response, error -> Void in
            if (error != nil) {
                println("\(error.localizedDescription)")
            }
            var err: NSError?

            var jsonResult: Array? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSArray?



            if (err != nil) {


                println("Can't connect using credentials")
                println("JSON Error \(err!.localizedDescription)")



            }

            if jsonResult?.count == 0 {

                println("Check digit removed from EAN-13")

                self.scannedBarcode.removeAtIndex(self.scannedBarcode.endIndex.predecessor())

                println(self.scannedBarcode)


                self.jsonComp()

                return

            }

            println("Well, this is 13 digit EAN-13")

            // 4

            let itemID: String! = jsonResult![0]["ITEM_ID"] as NSString
            let itemName: String! = jsonResult![0]["ITEM_Kitchen_Name"] as NSString
            let itemPrice: String! = jsonResult![0]["ITEM_Sale_Price"] as NSString


            println(itemID, itemName, itemPrice)

            self.selectedID = itemID
            self.selectedName = itemName
            self.selectedPrice = itemPrice


            dispatch_async(dispatch_get_main_queue(), {


                self.performSegueWithIdentifier("editPrice", sender: AnyObject?())

                //
            })
        })

        // 5
        jsonQuery.resume()


    }

    else if (barcodeLength == 12) {

        // UPC-A \\

        // ********** Database Function ********** Database Function ********** \\


        // 1
        let urlString: String = "http://\(hostString):\(portString)/barcode.php?&password=\(passString)&db=\(dbString)&barNum=\(self.scannedBarcode)"
        let url: NSURL?  = NSURL(string: urlString)!
        let urlSession = NSURLSession.sharedSession()


        //2
        let jsonQuery = urlSession.dataTaskWithURL(url!, completionHandler: { data, response, error -> Void in
            if (error != nil) {
                println("\(error.localizedDescription)")
            }
            var err: NSError?

            var jsonResult: Array? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSArray?



            if (err != nil) {


                println("Can't connect using credentials")
                println("JSON Error \(err!.localizedDescription)")



            }

            if jsonResult?.count == 0 {

                println("Check digit removed from UPC-A")

                self.scannedBarcode.removeAtIndex(self.scannedBarcode.endIndex.predecessor())

                println(self.scannedBarcode)


                self.jsonComp()

                return

            }

            println("Well, this is 12 digit UPC-A")

            // 4

            let itemID: String! = jsonResult![0]["ITEM_ID"] as NSString
            let itemName: String! = jsonResult![0]["ITEM_Kitchen_Name"] as NSString
            let itemPrice: String! = jsonResult![0]["ITEM_Sale_Price"] as NSString


            println(itemID, itemName, itemPrice)

            self.selectedID = itemID
            self.selectedName = itemName
            self.selectedPrice = itemPrice


            dispatch_async(dispatch_get_main_queue(), {


                self.performSegueWithIdentifier("editPrice", sender: AnyObject?())

                //
            })
        })

        // 5
        jsonQuery.resume()



    }

    else if (barcodeLength == 8) {



        // ********** Database Function ********** Database Function ********** \\


        // 1
        let urlString: String = "http://\(hostString):\(portString)/barcode.php?&password=\(passString)&db=\(dbString)&barNum=\(self.scannedBarcode)"
        let url: NSURL?  = NSURL(string: urlString)!
        let urlSession = NSURLSession.sharedSession()


        //2
        let jsonQuery = urlSession.dataTaskWithURL(url!, completionHandler: { data, response, error -> Void in
            if (error != nil) {
                println("\(error.localizedDescription)")
            }
            var err: NSError?

            var jsonResult: Array? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSArray?



            if (err != nil) {


                println("Can't connect using credentials")
                println("JSON Error \(err!.localizedDescription)")



            }

            if jsonResult?.count == 0 {

                println("Well, this is UPC-E")

                self.scannedBarcode.removeAtIndex(self.scannedBarcode.startIndex)
                self.scannedBarcode.removeAtIndex(self.scannedBarcode.endIndex.predecessor())


                println(self.scannedBarcode)


                self.jsonComp()

                return

            }

            println("Well, this is EAN-8")

            // 4

            let itemID: String! = jsonResult![0]["ITEM_ID"] as NSString
            let itemName: String! = jsonResult![0]["ITEM_Kitchen_Name"] as NSString

            if jsonResult![0]["ITEM_Sale_Price"] == nil {

                println("No Sale Price")

                dispatch_async(dispatch_get_main_queue(), {

                    HUDController.sharedController.hide(afterDelay: 0.1)

                })

                var refreshAlert = UIAlertController(title: "Camaleon Reports", message: "Barcode does not have a price set", preferredStyle: UIAlertControllerStyle.Alert)
                refreshAlert.addAction(UIAlertAction(title: "Retry", style: .Default, handler: { (action: UIAlertAction!) in
                    println("Yes Logic")

                }))


                self.presentViewController(refreshAlert, animated: true, completion: nil)

                return

            }

            let itemPrice: String! = jsonResult![0]["ITEM_Sale_Price"] as NSString


            println(itemID, itemName, itemPrice)

            self.selectedID = itemID
            self.selectedName = itemName
            self.selectedPrice = itemPrice


            dispatch_async(dispatch_get_main_queue(), {


                self.performSegueWithIdentifier("editPrice", sender: AnyObject?())

                //
            })
        })

        // 5
        jsonQuery.resume()

    } else {


        dispatch_async(dispatch_get_main_queue(), {

            HUDController.sharedController.hide(afterDelay: 0.1)

        })

        var refreshAlert = UIAlertController(title: "Camaleon Reports", message: "Barcode does not exist", preferredStyle: UIAlertControllerStyle.Alert)
        refreshAlert.addAction(UIAlertAction(title: "Retry", style: .Default, handler: { (action: UIAlertAction!) in
            println("Yes Logic")

        }))


        self.presentViewController(refreshAlert, animated: true, completion: nil)

        return


    }

}

Upvotes: 1

I don't think that the question is related to Swift at all. I presume that the barcode scanner is attached via a USB port. The scanner likely masquerades as a keyboard and "types" the decoded data. You'd need to refer to the scanner's documentation to figure out how to reconfigure the scanner to provide diagnostic data in addition to the decoded data. The diagnostics would include the type of barcode.

As a workaround, you can remove the last digit, try the database lookup, if that fails remove the first digit and try the lookup again.

Upvotes: 1

Related Questions