我已经在Xcode14.2中使用AVFoundation实现了QRCode扫描器,代码如下

code:当我在设备中运行此代码时,摄像头打开,但无法扫描二维码.为什么?我哪里错了.如何使用AVFoundation扫描二维码.请帮帮我.

我在下面的代码中遗漏了什么吗?请给我带路

如果我在模拟器中运行,它会显示您正在模拟器中运行

class QRCodeScannerVC: UIViewController, AVCaptureMetadataOutputObjectsDelegate {

var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!

override func viewDidLoad() {
    super.viewDidLoad()
    
    view.backgroundColor = UIColor.black
    captureSession = AVCaptureSession()
    
    guard let videoCaptureDevice = AVCaptureDevice.default(for: AVMediaType.video) else{
        print("you are running in simulator")
        return
    }
    let videoInput: AVCaptureDeviceInput
    
    do {
        videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
    } catch {
        return
    }
    
    if (captureSession.canAddInput(videoInput)) {
        captureSession.addInput(videoInput)
    } else {
        failed();
        return;
    }
    
    let metadataOutput = AVCaptureMetadataOutput()
    
    if (captureSession.canAddOutput(metadataOutput)) {
        captureSession.addOutput(metadataOutput)
        
        metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
        metadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.ean8, AVMetadataObject.ObjectType.ean13, AVMetadataObject.ObjectType.pdf417]
    } else {
        failed()
        return
    }
    
    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession);
    previewLayer.frame = view.layer.bounds;
    previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill;
    view.layer.addSublayer(previewLayer);
    
    captureSession.startRunning();
}

func failed() {
    let ac = UIAlertController(title: "Scanning not supported", message: "Your device does not support scanning a code from an item. Please use a device with a camera.", preferredStyle: .alert)
    ac.addAction(UIAlertAction(title: "OK", style: .default))
    present(ac, animated: true)
    captureSession = nil
    print("in simulator")
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    if (captureSession?.isRunning == false) {
        DispatchQueue.global(qos: .background).async {
            self.captureSession.startRunning();
        }
    }
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    
    if (captureSession?.isRunning == true) {
        captureSession.stopRunning();
    }
}

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection){
    captureSession.stopRunning()
    
    if let metadataObject = metadataObjects.first {
        let readableObject = metadataObject as! AVMetadataMachineReadableCodeObject;
        
        AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
        found(code: readableObject.stringValue!);
    }
    dismiss(animated: true)
}

func found(code: String) {
    print(code)
    self.showSingleButtonAlertWithoutAction(title: code)
}
override var prefersStatusBarHidden: Bool {
    return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}
}

推荐答案

我不确定,但这可能是原因,并提供this much of text in comment would not be readable,所以张贴它作为答案

在代码中,您将要扫描的元数据对象类型指定为[AVMetadataObject.ObjectType.ean8, AVMetadataObject.ObjectType.ean13, AVMetadataObject.ObjectType.pdf417].确保你试图扫描的二维码属于以下类别之一.如果你正在扫描常规的二维码,你应该改用AVMetadataObject.ObjectType.qr.

替换此行:

metadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.ean8, AVMetadataObject.ObjectType.ean13, AVMetadataObject.ObjectType.pdf417]

用这句话:

metadataOutput.metadataObjectTypes = [.qr]

我希望如果问题出在二维码类型上,那么这将会有所帮助!

Swift相关问答推荐

为什么ClosedRange<;Int&>包含的速度比预期慢340万倍?

如何使用AsyncTimerSequence获取初始时钟,然后在指定的时间间隔内开始迭代?

减小SF符号的边框宽度

领域异常中的相同方法:发送到实例的无法识别的 Select 器

标有@MainActor 的函数中的异步调用是否也在主线程上运行?

确定路径是否相交的有效方法

如何在不提交到应用store 的情况下在本地运行我的应用

格式化大货币数字

如何在 SwiftUI 中获取视图的位置

SwiftUI:决定键盘重叠的内容

为什么 Apple Scrumdinger Sample App 使用两个事实来源?

SwiftUI View Builder 参数无法更改状态

如何自己快速编写 Hashable 协议

Swift 覆盖实例变量

协议扩展中的where self是什么

如何在 SwiftUI 中以编程方式滚动列表?

在 Swift 中以编程方式更新约束的常量属性?

如何在 Swift 中判断变量的类型

如何在 SwiftUI 中的一个视图上显示两个alert ?

滑动侧边栏菜单 IOS 8 Swift