// // ScanViewController.swift // BlockEQ // // Created by Satraj Bambra on 2018-03-11. // Copyright © 2018 Satraj Bambra. All rights reserved. // import AVFoundation import UIKit protocol ScanViewControllerDelegate: class { func setQR(value: String) } class ScanViewController: UIViewController { var captureSession = AVCaptureSession() var videoPreviewLayer: AVCaptureVideoPreviewLayer? var qrCodeFrameView: UIView? weak var delegate: ScanViewControllerDelegate? private let supportedCodeTypes = [AVMetadataObject.ObjectType.upce, AVMetadataObject.ObjectType.code39, AVMetadataObject.ObjectType.code39Mod43, AVMetadataObject.ObjectType.code93, AVMetadataObject.ObjectType.code128, AVMetadataObject.ObjectType.ean8, AVMetadataObject.ObjectType.ean13, AVMetadataObject.ObjectType.aztec, AVMetadataObject.ObjectType.pdf417, AVMetadataObject.ObjectType.itf14, AVMetadataObject.ObjectType.dataMatrix, AVMetadataObject.ObjectType.interleaved2of5, AVMetadataObject.ObjectType.qr] required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } init() { super.init(nibName: String(describing: ScanViewController.self), bundle: nil) } override func viewDidLoad() { super.viewDidLoad() setupView() setupCamera() } func setupView() { navigationItem.title = "Scanning..." let image = UIImage(named:"close") let leftBarButtonItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(self.dismissView)) navigationItem.leftBarButtonItem = leftBarButtonItem view.backgroundColor = Colors.primaryDark } @objc func dismissView() { captureSession.stopRunning() videoPreviewLayer?.removeFromSuperlayer() dismiss(animated: true, completion: nil) } func setupCamera() { let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInDualCamera, .builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back) guard let captureDevice = deviceDiscoverySession.devices.first else { print("No Camera Found.") return } do { let input = try AVCaptureDeviceInput(device: captureDevice) captureSession.addInput(input) let captureMetadataOutput = AVCaptureMetadataOutput() captureSession.addOutput(captureMetadataOutput) captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) captureMetadataOutput.metadataObjectTypes = supportedCodeTypes } catch { print(error) return } videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill videoPreviewLayer?.frame = view.layer.bounds view.layer.addSublayer(videoPreviewLayer!) captureSession.startRunning() qrCodeFrameView = UIView() if let qrCodeFrameView = qrCodeFrameView { qrCodeFrameView.layer.borderColor = Colors.primaryDark.cgColor qrCodeFrameView.layer.borderWidth = 3.0 view.addSubview(qrCodeFrameView) view.bringSubview(toFront: qrCodeFrameView) } } } extension ScanViewController: AVCaptureMetadataOutputObjectsDelegate { func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { if metadataObjects.count == 0 { qrCodeFrameView?.frame = CGRect.zero return } let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject if supportedCodeTypes.contains(metadataObj.type) { let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj) qrCodeFrameView?.frame = barCodeObject!.bounds if let qrValue = metadataObj.stringValue { delegate?.setQR(value: qrValue) navigationItem.title = "Valid QR Code Found" perform(#selector(self.dismissView), with: nil, afterDelay: 0.8) } } } }