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

7

我正在编写一个条形码阅读器应用程序,但无法检测线性类型的条形码,例如Code 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)
                    }
                }
            }
        }

我使用了这个免费的在线条形码生成器来测试我的应用程序。我能够检测到大多数其他条形码,但是不能检测线性码。是否有人也遇到了这样的问题?


你需要展示你设置了哪些 metadataObjectTypes。确保包括新语法 [.code128] 中的 AVMetadataObjectTypeCode128Code - Leo Dabus
1
@LeoDabus 非常感谢,我完全忽略了这一部分。添加后一切都正常工作。 - Koh
1个回答

9

在设置 AVCaptureMetadataOutput 对象类型的时候,确保包含 AVMetadataObjectTypeCode128Code [.code128]

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

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

metadataOutput.metadataObjectTypes = metadataOutput.availableMetadataObjectTypes

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

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

关于你的实际代码,我有一些注记。如果要检查一个数组是否为空,不应该检查元素数量是否等于零。而是可以使用数组的一个叫做 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)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接