2017-12-09 22 views
1

私はこれに関する多くのスレッドとチュートリアルを見てきましたが、何も私の問題を解決しませんでした。私はこのを単純なQRコードアプリケーションの実装に従ってきましたが、コードは検出されませんでした.QR関連の質問の大半は、代行メソッドの古い名前に関連していました。私は更新されたデリゲートメソッドを使用していますが、まだ動作していないことを確認しました。QRコードが機能していません - デリゲートメソッドが呼び出されていません

これは私のコードです。どの愚かな間違いを私がしているのか見てください。

import UIKit 
import AVFoundation 

class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 

    @IBOutlet var messageLabel:UILabel! 
    @IBOutlet var topbar: UIView! 

    var captureSession:AVCaptureSession? 
    var videoPreviewLayer:AVCaptureVideoPreviewLayer? 
    var qrCodeFrameView:UIView? 

    let supportedCodeTypes = [AVMetadataObjectTypeQRCode, 
           AVMetadataObjectTypeCode39Code, 
           AVMetadataObjectTypeUPCECode, 
           AVMetadataObjectTypeCode39Mod43Code, 
           AVMetadataObjectTypeEAN13Code, 
           AVMetadataObjectTypeEAN8Code, 
           AVMetadataObjectTypeCode93Code, 
           AVMetadataObjectTypeCode128Code, 
           AVMetadataObjectTypePDF417Code, 
           AVMetadataObjectTypeAztecCode, 
           AVMetadataObjectTypeInterleaved2of5Code, 
           AVMetadataObjectTypeITF14Code, 
           AVMetadataObjectTypeDataMatrixCode] as [String] 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Get an instance of the AVCaptureDevice class to initialize a device object and provide the video as the media type parameter. 
     let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) 
     do { 
      // Get an instance of the AVCaptureDeviceInput class using the previous device object. 
      let input = try AVCaptureDeviceInput(device: captureDevice!) 

      // Initialize the captureSession object. 
      captureSession = AVCaptureSession() 

      // Set the input device on the capture session. 
      captureSession?.addInput(input) 

      // Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session. 
      let captureMetadataOutput = AVCaptureMetadataOutput() 
      captureSession?.addOutput(captureMetadataOutput) 

      // Set delegate and use the default dispatch queue to execute the call back 
      captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) 
      captureMetadataOutput.metadataObjectTypes = supportedCodeTypes 

      // Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer. 
      videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!) 
      videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill 
      videoPreviewLayer?.frame = view.layer.bounds 
      view.layer.addSublayer(videoPreviewLayer!) 

      // Start video capture. 
      captureSession?.startRunning() 

      // Move the message label and top bar to the front 
      view.bringSubview(toFront: messageLabel) 
      view.bringSubview(toFront: topbar) 

      // Initialize QR Code Frame to highlight the QR code 
      qrCodeFrameView = UIView() 

      if let qrCodeFrameView = qrCodeFrameView { 
       qrCodeFrameView.layer.borderColor = UIColor.green.cgColor 
       qrCodeFrameView.layer.borderWidth = 2 
       view.addSubview(qrCodeFrameView) 
       view.bringSubview(toFront: qrCodeFrameView) 
      } 

     } catch { 
      // If any error occurs, simply print it out and don't continue any more. 
      print(error) 
      return 
     } 
    } 

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


    // MARK: - AVCaptureMetadataOutputObjectsDelegate Methods 

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

     // Check if the metadataObjects array is not nil and it contains at least one object. 
     if metadataObjects.count == 0 { 
      qrCodeFrameView?.frame = CGRect.zero 
      messageLabel.text = "No QR/barcode is detected" 
      return 
     } 

     // Get the metadata object. 
     let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject 

     if supportedCodeTypes.contains(where: { $0 == metadataObj.type }) { 
      // If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds 
      let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj) 
      qrCodeFrameView?.frame = barCodeObject!.bounds 

      if metadataObj.stringValue != nil { 
       messageLabel.text = metadataObj.stringValue 
      } 
     } 
    } 
    } 

私は、iOSのバージョン9.3.5を使ってiPodでそれをテストしていてコードは、Xcodeの8.3.2と SWIFT 3です。

+0

あなたはもっと明示できますか?それはどこで失敗しますか?あなたはどのような行動をしていますか?あなたはコンソールメッセージを受け取りますか?コードのどの部分が実行されていますか(ブレークポイントやプリントでそれを試すことができます)? – barbarity

+0

ビデオは適切にキャプチャされていますが、コントロールは出力デリゲートメソッド "func metadataOutput(_ output:AVCaptureMetadataOutput、didOutput metadataObjects:[AVMetadataObject]、接続:AVCaptureConnection)で使用されません。バーコードは画面上で緑色の枠線で強調表示されません。 –

+0

実際にデリゲートをどこに設定しますか?ここでは提供されたコードでは表示されません。また、このページで 'delegate ='を検索すると、結果は得られません。 –

答えて

2

(iOS 10.x metadataOutput)は、captureOutputと呼ばれます。名前と署名を変更してください。完全に動作するはずです:

func captureOutput(_ output: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) { 
    // func code 
} 
+0

ありがとうございます。しかし、私は一点でクリアされていません。 iOS 11とiOS 10の両方のサポートで、両方の方法を追加する必要がありますか? AVCaptureConnectionからの接続:AVCaptureConnectionからの)[2] func captureOutput(_ output:AVCaptureOutput !, didOutputMetadataObjects metadataObjects:[Any] !,) ' –

+0

いいえ。システムはすでにそれを処理しており、iOS 11またはiOS 10を使用しているかどうかにかかわらず、何を意味するのかを理解しています。iOS 11がiOS 11の動作を知ることができないため、だから、古いバージョンでうまく動作します。 – barbarity

+1

1+ .................................... –

関連する問題