// // CommonControllerQR.swift // Wallet // // Created by Igor Danich on 03.08.2020. // Copyright © 2020 List. All rights reserved. // import AVFoundation import UIKit import WalletFoundation final class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { typealias OnCaptureClosure = (String) -> Void private let session = AVCaptureSession() private var previewLayer: AVCaptureVideoPreviewLayer! private let topColorView = UIView() var didCapture: OnCaptureClosure? override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = Asset.snow.color guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return } let videoInput: AVCaptureDeviceInput do { videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice) } catch { self.failed() return } if (self.session.canAddInput(videoInput)) { self.session.addInput(videoInput) } else { self.failed() return } let output = AVCaptureMetadataOutput() if (self.session.canAddOutput(output)) { self.session.addOutput(output) output.setMetadataObjectsDelegate(self, queue: .main) output.metadataObjectTypes = [.qr] } else { self.failed() return } self.previewLayer = AVCaptureVideoPreviewLayer(session: session) if let previewLayerFrameTop = UIApplication.shared.windows.first { self.previewLayer.frame = CGRect(x: 0, y: previewLayerFrameTop.safeAreaInsets.top, width: view.frameWidth, height: view.frameHeight - previewLayerFrameTop.safeAreaInsets.top) } self.previewLayer.videoGravity = .resizeAspectFill self.view.layer.addSublayer(self.previewLayer) self.session.startRunning() } private func failed() { Alert.system( title: "Scanning not supported", text: "Your device does not support scanning a code from an item. Please use a device with a camera." ) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.navigationController >>- { $0.navigationBar.backgroundColor = Asset.snow.color $0.navigationBar.isTranslucent = true } if !self.session.isRunning { self.session.startRunning() } } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) if self.session.isRunning { self.session.stopRunning() } } func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { self.session.stopRunning() guard let string = (metadataObjects.first as? AVMetadataMachineReadableCodeObject)?.stringValue else { return } AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate)) self.found(code: string) } private func found(code: String) { DispatchQueue.main.async { self.didCapture?(code) } } override var prefersStatusBarHidden: Bool { true } override var supportedInterfaceOrientations: UIInterfaceOrientationMask { .portrait } }