用于捕获 QR 码的代码在 Xcode8 和 Swift3 中似乎效果不佳

Posted

技术标签:

【中文标题】用于捕获 QR 码的代码在 Xcode8 和 Swift3 中似乎效果不佳【英文标题】:Code for capturing QR Code doesn't seem working well in Xcode8 and Swift3 【发布时间】:2016-09-11 16:00:41 【问题描述】:

我正在尝试在 Swift3 和 ios 10 beta 设备中使用 AVCaptureMetadataOutputObjectsDelegate 捕获 QR 码。

但是captureOutput 函数在二维码被设备的摄像头实际捕获时不会被调用。

有人对此有解决方案吗?如果是这样,请告诉我如何修复和正常工作。

谢谢,

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)")

    
  


【问题讨论】:

【参考方案1】:

在 Swift 3 中实现AVCaptureMetadataOutputObjectsDelegate 的方法头变成了这样:

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

[AnyObject] -> [Any],我没有检查你代码的其他部分,但至少,你需要解决这个问题。

【讨论】:

感谢您的快速提及。我确定了这一点,它起作用了!非常感谢您的帮助。 很高兴知道。我认为 Swift 开发受到主要版本之间方法标头等变化的数量的影响【参考方案2】:

Swift 4 中的委托方法

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

【讨论】:

【参考方案3】:

SWIFT 3:就我而言,这段代码解决了问题:

旧的错误代码

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)")
            
        
    

正确答案

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)")
            
        
    


【讨论】:

以上是关于用于捕获 QR 码的代码在 Xcode8 和 Swift3 中似乎效果不佳的主要内容,如果未能解决你的问题,请参考以下文章

QR(write2DBarcode)TCPDF上的代码

如何利用Halcon进行二维码QR码的识别

QR二维码原理

qr码和二维码区别

如何利用Halcon进行二维码QR码的识别

二维码生成原理