Read QR value using back camera.

import UIKit
import AVFoundation

class QRScanView: UIView {
    
    private let captureSession = AVCaptureSession()
    private var inputDevice: AVCaptureDeviceInput!
    private let outputMetadata = AVCaptureMetadataOutput()
    
    private var capturePreview: AVCaptureVideoPreviewLayer!
    private let boundView = UIView(frame: .zero)
    
    override func layoutSubviews() {
        super.layoutSubviews()
        initView()
    }
    
    private func initView() {
        guard inputDevice == nil, let device = AVCaptureDevice.default(for: .video) else {return}
        
        inputDevice = try! AVCaptureDeviceInput(device: device)
        captureSession.addInput(inputDevice)
        
        captureSession.addOutput(outputMetadata)
        outputMetadata.setMetadataObjectsDelegate(self, queue: .main)
        outputMetadata.metadataObjectTypes = [.qr]
        
        capturePreview = AVCaptureVideoPreviewLayer(session: captureSession)
        capturePreview.frame = bounds
        layer.addSublayer(capturePreview)
        
        boundView.backgroundColor = .clear
        boundView.layer.borderColor = UIColor.green.cgColor
        boundView.layer.borderWidth = 2
        addSubview(boundView)
        
        captureSession.startRunning()
    }
    
}

extension QRScanView: AVCaptureMetadataOutputObjectsDelegate {
    
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        guard let metadata = metadataObjects.first as? AVMetadataMachineReadableCodeObject, metadata.type == .qr else {
            boundView.frame = .zero
            return
        }
        
        if let object = capturePreview.transformedMetadataObject(for: metadata) {
            boundView.frame = object.bounds
        }
        
        if let value = metadata.stringValue {
            print("QRCode :", value)
        }
    }
    
}