1

I am trying to create QR Reader. However, when I open the window with scanner, it crashes with error "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVCaptureMetadataOutput setMetadataObjectTypes:] Unsupported type found - use -availableMetadataObjectTypes'"

This is my code:

import UIKit
import AVFoundation
import Alamofire
import SwiftyJSON

class CameraTwoViewController: UIViewController, 
AVCaptureMetadataOutputObjectsDelegate {

@IBOutlet weak var square: UIImageView!

var video = AVCaptureVideoPreviewLayer()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    //Creating session
    let session = AVCaptureSession()

    //Define capture devcie
    let captureDevice = AVCaptureDevice.default(for: .video)

    do
    {
        let input = try AVCaptureDeviceInput(device: captureDevice!)
    }
    catch
    {
        print ("ERROR")
    }

    let output = AVCaptureMetadataOutput()
    session.addOutput(output)

    output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)

    output.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]
    //output.metadataObjectTypes = [AVMetadataObject.availableMetadataObjectTypes.qr]

    video = AVCaptureVideoPreviewLayer(session: session)
    video.frame = view.layer.bounds
    view.layer.addSublayer(video)

    self.view.bringSubview(toFront: square)

    session.startRunning()
}

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
    if metadataObjects != nil && metadataObjects.count != 0 {
        if let object = metadataObjects[0] as? AVMetadataMachineReadableCodeObject {
            if object.type == AVMetadataObject.ObjectType.qr {
                let alert = UIAlertController(title: "Your code is:", message: object.stringValue, preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "Retake", style: .default, handler: nil))
                alert.addAction(UIAlertAction(title: "Copy", style: .default, handler: { (nil) in
                    UIPasteboard.general.string = object.stringValue
                }))
                present(alert, animated: true, completion: nil)
            }
        }
    }
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}

Thank you in advance!

1 Answers1

0

Try to add input to the session before you add output. Something like that:

func configureScanner() {

    guard let captureDevice = AVCaptureDevice.default(for: .video) else {
        return
    }

    var input: AVCaptureDeviceInput?
    do {
        input = try AVCaptureDeviceInput(device: captureDevice)
    } catch let error {
        print(error.localizedDescription)
    }

    guard let indeedInput = input else {
        return
    }
    captureSession = AVCaptureSession()
    captureSession!.addInput(indeedInput)

    let captureMetadataOutput = AVCaptureMetadataOutput()
    captureSession!.addOutput(captureMetadataOutput)

    captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
    captureMetadataOutput.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]

    ...
  }
Aleksey Shevchenko
  • 1,159
  • 1
  • 11
  • 23