Scan Barcode
When you want to use scan the barcode from your iPhone or iPad. You have to import the AVFoundation library (Just write import AVFoundation in a class where you are using barcode scanning no need to add a framework) to use a barcode scanner. You have to use the AVCaptureMetadataOutputObjectsDelegate delegate method to use AVCapture classes. Declare these variables in your class where you want to implement the Scanner action:-
1 2 3 |
var captureSession:AVCaptureSession? var videoPreviewLayer:AVCaptureVideoPreviewLayer? var qrCodeFrameView:UIView? |
Then implement the video capturing using AVCaptureSession. in qrcodeFrameView is the view where the camera scan the barcode so you can change its height and width according to your view. First, you have to create the instance of the AVCaptureDeviceInput.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) do { // Get an instance of the AVCaptureDeviceInput class using the previous device object. let input = try AVCaptureDeviceInput(device: captureDevice) // Initialize the captureSession object. captureSession = AVCaptureSession() // Set the input device on the capture session. captureSession?.addInput(input) // Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session. let captureMetadataOutput = AVCaptureMetadataOutput() captureSession?.addOutput(captureMetadataOutput) // Set delegate and use the default dispatch queue to execute the call back captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) captureMetadataOutput.metadataObjectTypes = supportedCodeTypes // Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer. videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill videoPreviewLayer?.frame = view.layer.bounds view.layer.addSublayer(videoPreviewLayer!) // Start video capture. captureSession?.startRunning() // Move the message label and top bar to the front view.bringSubview(toFront: message) view.bringSubview(toFront: topBar) // Initialize QR Code Frame to highlight the QR code qrCodeFrameView = UIView() if let qrCodeFrameView = qrCodeFrameView { qrCodeFrameView.layer.borderColor = UIColor.green.cgColor qrCodeFrameView.layer.borderWidth = 2 view.addSubview(qrCodeFrameView) view.bringSubview(toFront: qrCodeFrameView) } } catch { // If any error occurs, simply print it out and don't continue any more. print(error) return } |
Then you gave to use the delegate method: –
1 2 |
class BarcodeScannner: UIViewController , AVCaptureMetadataOutputObjectsDelegate { } |
And override the delegate method to get the functionality of barcode from which you get to know the text of barcode and you can use this text anywhere where you want to use and you can also set the timer 1 sec so from there you will get the exact value of barcode text:-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) { // Check if the metadataObjects array is not nil and it contains at least one object. if metadataObjects == nil || metadataObjects.count == 0 { qrCodeFrameView?.frame = CGRect.zero message.text = "No QR/barcode is detected" return } // Get the metadata object. let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject if supportedCodeTypes.contains(metadataObj.type) { // If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj) qrCodeFrameView?.frame = barCodeObject!.bounds if metadataObj.stringValue != nil { print( metadataObj.stringValue) message.text = metadataObj.stringValue scannedCode = metadataObj.stringValue Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.dismissCont), userInfo: nil, repeats: true) } } } |