                 
                 captureMetadataOutput = AVCaptureMetadataOutput()
                 captureSession.addOutput(captureMetadataOutput)
-                
+                captureMetadataOutput.metadataObjectTypes = metadataTypes.filter { captureMetadataOutput.availableMetadataObjectTypes.contains($0) }
                 captureMetadataOutput.setMetadataObjectsDelegate(self, queue:dispatchQueue)
-                #if swift(>=4.0)
-                    captureMetadataOutput.metadataObjectTypes = [
-                        AVMetadataObject.ObjectType.qr,
-                        AVMetadataObject.ObjectType.upce,
-                        AVMetadataObject.ObjectType.code39,
-                        AVMetadataObject.ObjectType.code39Mod43,
-                        AVMetadataObject.ObjectType.ean13,
-                        AVMetadataObject.ObjectType.ean8,
-                        AVMetadataObject.ObjectType.code93,
-                        AVMetadataObject.ObjectType.code128,
-                        AVMetadataObject.ObjectType.pdf417,
-                        AVMetadataObject.ObjectType.aztec
-                    ]
-                #else
-                    captureMetadataOutput.metadataObjectTypes = [
-                        AVMetadataObjectTypeQRCode,
-                        AVMetadataObjectTypeUPCECode,
-                        AVMetadataObjectTypeCode39Code,
-                        AVMetadataObjectTypeCode39Mod43Code,
-                        AVMetadataObjectTypeEAN13Code,
-                        AVMetadataObjectTypeEAN8Code,
-                        AVMetadataObjectTypeCode93Code,
-                        AVMetadataObjectTypeCode128Code,
-                        AVMetadataObjectTypePDF417Code,
-                        AVMetadataObjectTypeAztecCode
-                    ]
-                #endif
             case .takePhoto: break
             }
+            
             captureImageOutput.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]
             videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
-            #if swift(>=4.0)
-                videoPreviewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
-            #else
-                videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
-            #endif
+            videoPreviewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
             videoPreviewLayer.frame = inView.layer.bounds
             inView.layer.addSublayer(videoPreviewLayer)
             videoPreviewView = inView

    open private(set) var isReading = false
    open var userData: Any?
    open var mode: CNLCodeScannerMode = .scanCode
    
    @discardableResult
    open func startReading(_ inView: UIView, isFront: Bool) -> Bool {
        #if swift(>=4.0)
            let devices = AVCaptureDevice.devices(for: AVMediaType.video)
            // most cases: we run in simulator
            guard devices.count != 0 else {
                delegate?.codeScannerError(self)
                return false
            }
        #else
            let possibleDevices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo)
            // most cases: we run in simulator
            guard let devices = possibleDevices, devices.count != 0 else {
                delegate?.codeScannerError(self)
                return false
            }
        #endif
        
        captureDevice = nil
        for device in devices {
            #if swift(>=4.0)
                if isFront {
                    if device.position == .front {
                        captureDevice = device
                        break
                    }
                } else {
                    if device.position == .back {
                        captureDevice = device
                        break
                    }
                }
            #else
                if let device = device as? AVCaptureDevice {
                    if isFront {
                        if device.position == .front {
                            captureDevice = device
                            break
                        }
                    } else {
                        if device.position == .back {
                            captureDevice = device
                            break
                        }
                    }
                }
            #endif
        }
        
        if captureDevice == nil {

    }
    
    // AVCaptureMetadataOutputObjectsDelegate delegate
    public func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        if !isReading {
            isReading = true
            guard
                let metadataObj = metadataObjects.first as? AVMetadataMachineReadableCodeObject
                else { return }
            asyncMain {
                let objectFrame = UIView()
                objectFrame.backgroundColor = UIColor.clear
                
                //self.highlightView.frame = self.videoPreviewLayer.transformedMetadataObjectForMetadataObject(metadataObj).bounds
                //self.highlightView.hidden = false
                self.captureImage { image in
                    self.delegate?.codeScanner(self, didScanObject: metadataObj, screenshot: image)
                    self.stopReading()
                }
            }
        }
