Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
537 views
in Technique[技术] by (71.8m points)

Swift: Unable to detect linear type Barcodes

I am writing a barcode reader app but I am unable to detect linear type barcodes, ie code 128. I have no issues with Qr codes, EAN13 types and ISBN types. My code is pretty straightforward:

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {

        if metadataObjects.count != 0 {
            if let object = metadataObjects[0] as? AVMetadataMachineReadableCodeObject {
                if object.type == AVMetadataObject.ObjectType.qr {
                    if let text = object.stringValue {
                        print(text)

                        session.stopRunning()

                        let alertVC = UIAlertController(title: "QR Code", message: text, preferredStyle: UIAlertControllerStyle.alert)
                        alertVC.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action) in
                            self.session.startRunning()
                        }))
                        present(alertVC, animated: true, completion: nil)
                    }
                } else {
                    if let text = object.stringValue {
                        print("Other code detected: ", text)
                    }
                }
            }
        }

I used this free online barcode generator to test my app. I am able to detect most of other barcodes, except Linear Codes. Has anyone encountered such problems too?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Make sure to include AVMetadataObjectTypeCode128Code [.code128] when setting AVCaptureMetadataOutput object types metadataObjectTypes.

metadataOutput.metadataObjectTypes = [.qr, .ean13, .code128]

If you would like to allow all available metadata object types you can use AVCaptureMetadataOutput property availableMetadataObjectTypeswhich return all available types:

metadataOutput.metadataObjectTypes = metadataOutput.availableMetadataObjectTypes

If you would like to allow all of then except the faces which is the first one, you can drop the first element of the availableMetadataObjectTypes. Note that Apple might change the metadata elements order in the near future so it is better to manually select only the barcode types required by your app:

metadataOutput.metadataObjectTypes =  Array(metadataOutput.availableMetadataObjectTypes.dropFirst())

Just a few notes on your actual code. You shouldn't check the elements count if it is equal to zero to check if it is empty. Array has a property called isEmpty exactly for that if !metadataObjects.isEmpty { //.... Another option is if only the first element of the array is used I recommend using Array .first instead of subscript [0] which returns an optional element AVMetadataObject? and AVMetadataObject.ObjectType is redundant in your comparison:

if let object = metadataObjects.first as? AVMetadataMachineReadableCodeObject {
    if object.type == .qr {
        if let text = object.stringValue {
            print(text)
            session.stopRunning()
            let alertVC = UIAlertController(title: "QR Code", message: text, preferredStyle: .alert)
            alertVC.addAction(UIAlertAction(title: "Ok", style: .default) { _ in
                self.session.startRunning()
            })
            present(alertVC, animated: true)
        }
    }
    else
    if let text = object.stringValue {
        print("Other code detected: ", text)
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...