Skip to content

Instantly share code, notes, and snippets.

@hassanvfx
Created June 23, 2023 02:04
Show Gist options
  • Save hassanvfx/78ef6c0caecea3a8a4964bc06353fd8d to your computer and use it in GitHub Desktop.
Save hassanvfx/78ef6c0caecea3a8a4964bc06353fd8d to your computer and use it in GitHub Desktop.
SwiftUI QRCode Scanner
import SwiftUI
import AVFoundation
struct QRCodeScannerView: UIViewControllerRepresentable {
var handleQRCode: (String) -> Void
func makeUIViewController(context: Context) -> QRCodeScannerViewController {
let viewController = QRCodeScannerViewController()
viewController.handleQRCode = handleQRCode
return viewController
}
func updateUIViewController(_ uiViewController: QRCodeScannerViewController, context: Context) { }
}
class QRCodeScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var handleQRCode: ((String) -> Void)?
var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!
override func viewDidLoad() {
super.viewDidLoad()
captureSession = AVCaptureSession()
guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return }
let videoInput: AVCaptureDeviceInput
do {
videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
} catch {
return
}
if (captureSession.canAddInput(videoInput)) {
captureSession.addInput(videoInput)
} else {
return
}
let metadataOutput = AVCaptureMetadataOutput()
if (captureSession.canAddOutput(metadataOutput)) {
captureSession.addOutput(metadataOutput)
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
metadataOutput.metadataObjectTypes = [.qr]
} else {
return
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.frame = view.layer.bounds
previewLayer.videoGravity = .resizeAspectFill
view.layer.addSublayer(previewLayer)
captureSession.startRunning()
}
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
captureSession.stopRunning()
if let metadataObject = metadataObjects.first {
guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
guard let stringValue = readableObject.stringValue else { return }
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
handleQRCode?(stringValue)
}
dismiss(animated: true)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if (captureSession?.isRunning == true) {
captureSession.stopRunning()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment