Scanner App using SwiftUI

Nabendu Biswas
6 min readNov 8, 2023

In this post we will continue our SwiftUI journey which started in the earlier post. Here, we will create a a bit more advanced in SwiftUI project.

This post have been inspired by the awesome SwiftUI Fundamentals video by Sean Allen.

So, first start XCode and click on File -> New and Project.

After that in iOS select App and then click on Next button.

Next, give the product a name which is BarcodeScanner in our case. Also, we will choose the Interface as SwiftUI.

Next, we will save the project on the Desktop.

Our project will be opened with the Content View showing the project.

We will change the default name of our project, by right-clicking on ContentView and the Refactor -> Rename.

After that we have given the name BarcodeScannerView to it.

Now, we will add a NavigationView with a VStack. Inside it we will have a Rectangle and a text Scanned Barcode. We will also have the text, Not Yet Scanned. And also a navigation title with Barcode Scanner.

Since, we need to have access to Camera we need to first click on BarcodeScanner. After that in the next screen click on TARGETS and then BarcodeScanner.

After that in the Bundle name click on the + sign.

Next, write Privacy and scroll down.

Select the option Privacy — Camera Usage Description.

We also need to give a value. So, write “We need the Camera to Scan Barcodes”.

Now, we will create a new file so click on Cmd + N and select a Swift File.

Now, the new file is called ScannerViewController.swift file. Here, we have imported UIKit and AVFoundation.

Now, we have a class called ScannerVC which will have CaptureSession and PreviewLayer variables. In the init() of the class, we are taking the scannerDelegate.

Next, we have a setupCaptureSession function which will capture the video.

Next, in the captureSession we will check for input and output. And add the input and output respectively. Next, we will also get the previewLayer.

Next, we will add code in the extension ScannerVC. Here, we will have a function metadataOutput, which will have metadataObjects, machineReadableObject and barcode.

Now, we will add an enum CameraError which will contain two case for errors. And will also add a func called disSurface which will use this error in the protocol.

Now, we will use these two errors at various part of our function setupCaptureSession.

We will also add the error call in our extension ScannerVC.

Now, we will create a viewDidLoad() and call the setupCaptureSession here. We will also have a viewDidLayoutSubviews() calling our previewLayer.

Next, we will create a new SwiftUI View file.

In the new file ScannerView.swift, we will have the makeUIViewController call the ScannerVC from the earlier file. We are also using the error and barcode in this file.

Next, in the root file of BarcodeScannerView.swift we will call the ScannerView().

Now, if we run the app in XCode, we will get “Something is wrong with the camera” error.

Next, we will create a state of scannedCode and pass it in ScannerView in BarcodeScannerView.swift file. Now, depending upon whether it’s empty, we will show the text “Not Yet Scanned” or the scannedCode.

Back in the ScannerView.swift we will have the scannedCode value through binding. Next, inside the Coordinator class we will map the barcode to the scannedCode.

Now, in the BarcodeScannerView.swift file, we will have an struct called AlertItem. Using it we will create a struct called AlertContext, which will have two AlertItem.

In the ScannerViewController.swift file, we will have an enum called CameraError, which will contain two cases.

We will now add an empty print statement in the ScannerView.swift file, or else we will get error.

We will also update the AlertItem in BarcodeScannerView.swift file, with an id.

Next, we will update the alert in the BarcodeScannerView.swift file, with an Alert item.

We will also add a binding for AlertItem in the ScannerView.swift file.

The ScannerView in the BarcodeScannerView.swift file, will also get the alertItem now.

We will update the didSurface function in the ScannerView.swift file. Here, we will put error cases.

Now, if we again start the simulator, we will get the correct error with the pop-up.

Our app is complete, but we will refactor it a bit by creating a new Swift File.

Here, we have moved our alerts to a new file called Alert.swift.

This completes our small swift app. You can find the code for the same here.

--

--

Nabendu Biswas

Architect, ReactJS & Ecosystem Expert, Youtuber, Blogger