代码之家  ›  专栏  ›  技术社区  ›  Rutger Huijsmans

扫描二维码

  •  2
  • Rutger Huijsmans  · 技术社区  · 6 年前

    我上了以下课程,试图扫描二维码。我只是因为某种原因不能让它工作。我可以展示这个ViewController,它输出相机看到的东西,但每当我尝试扫描QR时,什么都不会发生。

    知道遗漏了什么吗?

    import AVFoundation
    import UIKit
    
    class ScannerViewController: 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: .video) else { 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 = [.qr]
            } else {
                failed()
                return
            }
    
            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
            previewLayer.frame = view.layer.bounds
            previewLayer.videoGravity = .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
        }
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
    
            if (captureSession?.isRunning == false) {
                captureSession.startRunning()
            }
        }
    
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
    
            if (captureSession?.isRunning == true) {
                captureSession.stopRunning()
            }
        }
    
        func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
            captureSession.stopRunning()
    
            if let metadataObject = metadataObjects.first {
                guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
                guard let stringValue = readableObject.stringValue else { return }
                AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
                found(code: stringValue)
            }
    
            dismiss(animated: true)
        }
    
        func found(code: String) {
            print(code)
        }
    
        override var prefersStatusBarHidden: Bool {
            return true
        }
    
        override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
            return .portrait
        }
    }
    

    我还为plist添加了以下值:

    key: Privacy - Camera Usage Description 
    value: $(PRODUCT_NAME) camera use
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Rutger Huijsmans    6 年前

    您的扫描代码检查将在以下学员中进行:

    func metadataOutput(\uOutput:AvCaptureMataOutput,didOutput metadataObjects:[AVMetadataObject],来自连接:AVCaptureConnection)

    您的代码如下:

    import AVFoundation
    import UIKit
    
    class ScannerViewController: 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: .video) else { 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 = [.qr]
            } else {
                failed()
                return
            }
    
            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
            previewLayer.frame = view.layer.bounds
            previewLayer.videoGravity = .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
        }
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
    
            if (captureSession?.isRunning == false) {
                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 {
                guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
                guard let stringValue = readableObject.stringValue else { return }
                AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
                found(code: stringValue)
            }
    
            dismiss(animated: true)
        }
    
        func found(code: String) {
            print(code)
        }
    
        override var prefersStatusBarHidden: Bool {
            return true
        }
    
        override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
            return .portrait
        }
    }