// // 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! 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: self.session) self.previewLayer.frame = self.view.bounds self.previewLayer.videoGravity = .resizeAspectFill self.view.layer.addSublayer(self.previewLayer) DispatchQueue.global(qos: .background).async { [weak self] in 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 = .clear $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 { [weak self] in self?.didCapture?(code) } } override var prefersStatusBarHidden: Bool { true } override var supportedInterfaceOrientations: UIInterfaceOrientationMask { .portrait } }