Swift:无法检测线性类型条形码

Koh*_*Koh 7 barcode-scanner swift

我正在编写一个条形码阅读器应用程序,但无法检测线性类型条形码,即代码 128。我对 Qr 代码、EAN13 类型和 ISBN 类型没有任何问题。我的代码非常简单:

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)
                    }
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

我使用这个免费的在线条形码生成器来测试我的应用程序。我能够检测除线性代码之外的大多数其他条形码。有人也遇到过这样的问题吗?

Leo*_*bus 9

[.code128]设置AVCaptureMetadataOutput对象类型时,请确保包含 AVMetadataObjectTypeCode128Code metadataObjectTypes

metadataOutput.metadataObjectTypes = [.qr, .ean13, .code128]
Run Code Online (Sandbox Code Playgroud)

如果您想允许所有可用的元数据对象类型,您可以使用 返回所有可用类型的AVCaptureMetadataOutput属性:availableMetadataObjectTypes

metadataOutput.metadataObjectTypes = metadataOutput.availableMetadataObjectTypes
Run Code Online (Sandbox Code Playgroud)

如果您想允许除第一个面之外的所有面,您可以删除 availableMetadataObjectTypes 的第一个元素。请注意,Apple 可能会在不久的将来更改元数据元素顺序,因此最好仅手动选择应用程序所需的条形码类型:

metadataOutput.metadataObjectTypes =  Array(metadataOutput.availableMetadataObjectTypes.dropFirst())
Run Code Online (Sandbox Code Playgroud)

只是关于您的实际代码的一些注释。如果元素计数等于零,则不应检查元素计数是否为空。Array 有一个名为 isEmpty 的属性正是用于此目的if !metadataObjects.isEmpty { //...。另一种选择是,如果仅使用数组的第一个元素,我建议使用 Array.first而不是下标[0],它返回一个可选元素AVMetadataObject?,并且AVMetadataObject.ObjectType在比较中是多余的:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)