IOS 11 – Swift 4 – QR Code & Barcode Reader Example
This is an example code of QR Code & Barcode reader with using IOS 11 and Swift 4.0.
To prevent our QR code reader from appearing on the app’s main screen, I created “ScannerViewController” class. Also I added a TabBar item to pass that screen. If you want to apply another method to passing, you can remove code part begin with “required init”.
import AVFoundation
import UIKit
class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
required init?(coder aDecoder: NSCoder){
super.init(coder: aDecoder)
tabBarItem = UITabBarItem(title: "QR Code", image: UIImage(named: "if_shopping"), tag: 2)
}
class CameraView: UIView {
override class var layerClass: AnyClass {
get {
return AVCaptureVideoPreviewLayer.self
}
}
override var layer: AVCaptureVideoPreviewLayer {
get {
return super.layer as! AVCaptureVideoPreviewLayer
}
}
}
var cameraView: CameraView!
override func loadView() {
cameraView = CameraView()
view = cameraView
}
let session = AVCaptureSession()
let sessionQueue = DispatchQueue(label: AVCaptureSession.self.description(), attributes: [], target: nil)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
session.beginConfiguration()
let videoDevice = AVCaptureDevice.default(for: .video)
1
if (videoDevice != nil) {
let videoDeviceInput = try? AVCaptureDeviceInput(device: videoDevice!)
if (videoDeviceInput != nil) {
if (session.canAddInput(videoDeviceInput!)) {
session.addInput(videoDeviceInput!)
}
}
let metadataOutput = AVCaptureMetadataOutput()
if (session.canAddOutput(metadataOutput)) {
session.addOutput(metadataOutput)
metadataOutput.metadataObjectTypes = [
.ean13,
.qr
]
metadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
}
}
session.commitConfiguration()
cameraView.layer.session = session
cameraView.layer.videoGravity = .resizeAspectFill
let videoOrientation: AVCaptureVideoOrientation
switch UIApplication.shared.statusBarOrientation {
case .portrait:
videoOrientation = .portrait
case .portraitUpsideDown:
videoOrientation = .portraitUpsideDown
case .landscapeLeft:
videoOrientation = .landscapeLeft
case .landscapeRight:
videoOrientation = .landscapeRight
default:
videoOrientation = .portrait
}
cameraView.layer.connection?.videoOrientation = videoOrientation
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
sessionQueue.async {
self.session.startRunning()
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
sessionQueue.async {
self.session.stopRunning()
}
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
// Update camera orientation
let videoOrientation: AVCaptureVideoOrientation
switch UIDevice.current.orientation {
case .portrait:
videoOrientation = .portrait
case .portraitUpsideDown:
videoOrientation = .portraitUpsideDown
case .landscapeLeft:
videoOrientation = .landscapeRight
case .landscapeRight:
videoOrientation = .landscapeLeft
default:
videoOrientation = .portrait
}
cameraView.layer.connection?.videoOrientation = videoOrientation
}
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
if (metadataObjects.count > 0 && metadataObjects.first is AVMetadataMachineReadableCodeObject) {
let scan = metadataObjects.first as! AVMetadataMachineReadableCodeObject
let alertController = UIAlertController(title: "Barcode Scanned", message: scan.stringValue, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler:nil))
present(alertController, animated: true, completion: nil)
}
}
}
The program wants permission to access camera. For that permission screen, we need to add a row in “Info.plist” file. Add “Privacy – Camera Usage Description” with value “Can program access your camera for QR reading?” or somethink like this.

Lastly, create an empty View Controller in Main.storyboard and connect it to “ScannerViewController” class.
Important tips: Your Mac simulator may not work for qr code reader. Please use real iPhone for simulating.
You can ask your questions in the comments part of the page.
