junet
junet

Reputation: 53

Code for capturing QR Code doesn't seem working well in Xcode8 and Swift3

I'm trying to capture QR code using AVCaptureMetadataOutputObjectsDelegate in Swift3 and iOS 10 beta device.

But captureOutput function is not called when QR code is actually captured by device's camera.

Does anyone have a solution for this? If so, please let me know how to fix and work properly.



Thanks,

import UIKit
import AVFoundation

class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {

  override func viewDidLoad() {
    super.viewDidLoad()

    let mySession: AVCaptureSession! = AVCaptureSession()
    let devices = AVCaptureDevice.devices()
    var myDevice: AVCaptureDevice!

    for device in devices! {
      if((device as AnyObject).position == AVCaptureDevicePosition.back){
        myDevice = device as! AVCaptureDevice
      }
    }

    let myVideoInput = try! AVCaptureDeviceInput.init(device: myDevice)

    if mySession.canAddInput(myVideoInput) {
      mySession.addInput(myVideoInput)
    }

    let myMetadataOutput: AVCaptureMetadataOutput! = AVCaptureMetadataOutput()

    if mySession.canAddOutput(myMetadataOutput) {
      mySession.addOutput(myMetadataOutput)
      myMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
      myMetadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
    }

    let myVideoLayer = AVCaptureVideoPreviewLayer.init(session: mySession)
    myVideoLayer?.frame = self.view.bounds
    myVideoLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
    self.view.layer.addSublayer(myVideoLayer!)

    mySession.startRunning()
  }


  // MARK: - AVCaptureMetadataOutputObjectsDelegate

  // This function is not called despite capturing QR code  
  func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, from connection: AVCaptureConnection!) {
    if metadataObjects.count > 0 {
      let qrData: AVMetadataMachineReadableCodeObject  = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
      print("\(qrData.type)")
      print("\(qrData.stringValue)")

    }
  }

}

Upvotes: 1

Views: 1450

Answers (3)

Lawliet
Lawliet

Reputation: 3499

The delegate method in Swift 4

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {}

Upvotes: 3

jazzbpn
jazzbpn

Reputation: 7318

SWIFT 3: In my case this code solve the problem:

Old INCORRECT CODE

private func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
    for item in metadataObjects {
        if let metadataObject = item as? AVMetadataMachineReadableCodeObject {
            if metadataObject.type == AVMetadataObjectTypeQRCode {
                print("QR Code: \(metadataObject.stringValue)")
            }
        }
    }
}

CORRECT ANSWER

func captureOutput(_ captureOutput: AVCaptureOutput!,
                   didOutputMetadataObjects metadataObjects: [Any]!,
                   from connection: AVCaptureConnection!) {
    for item in metadataObjects {
        if let metadataObject = item as? AVMetadataMachineReadableCodeObject {
            if metadataObject.type == AVMetadataObjectTypeQRCode {
                print("QR Code: \(metadataObject.stringValue)")
            }
        }
    }

}

Upvotes: 0

OOPer
OOPer

Reputation: 47876

The method header to implement AVCaptureMetadataOutputObjectsDelegate in Swift 3 has become like this:

func captureOutput(_ captureOutput: AVCaptureOutput!,
                   didOutputMetadataObjects metadataObjects: [Any]!,
                   from connection: AVCaptureConnection!) {

[AnyObject] -> [Any], I haven't checked other parts of your code, but at least, you need to fix this.

Upvotes: 10

Related Questions