Read QR code with Swift/iOS

MLBoy
2 min readJan 3, 2024

--

  • How to do it with AVFoundation
  • AVCaptureMetadataOutputObjectsDelegate

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection)

You can obtain the QR code detection result for each frame with the delegate method named .

Below is the code for camera settings and QR code detection, and with this you can draw the QR code area.


class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
private var captureSession: AVCaptureSession!
private var preview = UIView()
private lazy var previewLayer: AVCaptureVideoPreviewLayer = {
let layer = AVCaptureVideoPreviewLayer(session: self.captureSession)
layer.frame = preview.bounds
layer.videoGravity = .resizeAspectFill
layer.connection?.videoOrientation = .portrait
return layer
}()
private var qrCodeFrameView = UIView()
var qrCodeLabel = UILabel()

override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(preview)
preview.frame = view.bounds
qrCodeFrameView.layer.borderColor = UIColor.red.cgColor
qrCodeFrameView.layer.borderWidth = 2
view.addSubview(qrCodeFrameView)
view.bringSubviewToFront(qrCodeFrameView)
qrCodeFrameView.isHidden = true
view.addSubview(qrCodeLabel)
let captureDevice = AVCaptureDevice.default(for: .video)

do {
let input = try AVCaptureDeviceInput(device: captureDevice!)
captureSession = AVCaptureSession()
captureSession?.addInput(input)

let output = AVCaptureMetadataOutput()
captureSession?.addOutput(output)

output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
output.metadataObjectTypes = [.qr]
preview.layer.addSublayer(previewLayer)
DispatchQueue.global(qos: .userInitiated).async {
self.captureSession?.startRunning()
}
} catch {
print("Error setting up capture session: \(error.localizedDescription)")
}
}

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
if let metadataObject = metadataObjects.first {
guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }

if let stringValue = readableObject.stringValue {
print("QR Code Value: \(stringValue)")
DispatchQueue.main.async {
self.qrCodeLabel.text = stringValue
}
}

if let barCodeObject = previewLayer.transformedMetadataObject(for: metadataObject) {
print(barCodeObject)
let qrCodeFrame = barCodeObject.bounds
DispatchQueue.main.async {
self.qrCodeLabel.isHidden = false
self.qrCodeFrameView.isHidden = false
self.qrCodeFrameView.frame = qrCodeFrame
self.qrCodeLabel.frame = CGRect(x: self.qrCodeFrameView.frame.minX, y: self.qrCodeFrameView.frame.minY-60, width: 300, height: 60)
}
} else {
DispatchQueue.main.async {
self.qrCodeFrameView.isHidden = true
}
}
}
}

🐣

I’m a freelance engineer.
Work consultation
Please feel free to contact us with a brief development description.
rockyshikoku@gmail.com

I am creating applications using machine learning and AR technology.

I send machine learning / AR related information.

GitHub

Twitter
Medium

--

--

MLBoy
MLBoy

No responses yet