2017-10-20 7 views
0

私の友人と私は最近swift 3.2からswift 4に更新しました。残念ながら、私たちのプロジェクトはQRリーダー機能で正しく機能しなくなりました。ビデオ出力がうまく動作するので、ページをロードすると、電話機を見ているときに画面が表示されます。ただし、サイジングボックスを画面に配置したり、その前にあるQRコードを認識することはありません。速報4回からのアップデートアプリ

import UIKit 
    import AVFoundation 
    class ScanViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { 

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

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

    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 = [AVMetadataObjectTypeQRCode] 

      // 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!) 

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

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

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

      if let qrCodeFrameView = qrCodeFrameView { 
       qrCodeFrameView.layer.borderColor = UIColor.randomColor().cgColor 
       qrCodeFrameView.layer.borderWidth = 4 
       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 
     } 
    } 

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

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

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

     if metadataObj.type == AVMetadataObjectTypeQRCode { 
      // 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 { //Output 
       messageLabel.text = metadataObj.stringValue 

       performSegue(withIdentifier: "QRFound", sender: self) 
      } 
     } 
    } 

    @IBAction func cancel(_ sender: UIButton) { 
     if let owningNavController = navigationController { 
      owningNavController.popViewController(animated: true) 
     } 
     dismiss(animated: true, completion: nil) 
    } 
} 
+1

私が試したことや起こったことを画面やデバッガで詳しく説明した場合、私は役に立ちます。 –

答えて

0

代理人機能が正しくないため、決して呼び出されません。正しいものは次のとおりです。

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

documentation pageを参照してください。 スウィフト4で変更されたようです。

EDIT:this answerも参照してください。

関連する問題