SwiftUI and Custom Barcode Scanner in iOS Development with Swift

iOS Guru
3 min readMar 28, 2023

The introduction of SwiftUI in iOS development has revolutionized the way developers create apps. With its declarative syntax, developers can create complex user interfaces with fewer lines of code. One of the most popular use cases for SwiftUI is creating custom barcode scanners. This article will discuss how to create a custom barcode scanner with SwiftUI and provide sample source code.

Creating a Custom Barcode Scanner with SwiftUI

Creating a custom barcode scanner with SwiftUI is a straightforward process. The first step is to set up the AVFoundation framework. This framework is used to capture the barcode from the camera. To do this, open the project’s Info.plist file and add the following key:

<key>NSCameraUsageDescription</key>
<string>This app needs access to the camera to scan barcodes.</string>

Next, create a new SwiftUI view called BarcodeScannerView. This view will be responsible for displaying the camera feed and capturing the barcode. At the top of the view, add the following code:

import AVFoundation

struct BarcodeScannerView: View {
@State private var captureSession: AVCaptureSession?
@State private var videoPreviewLayer: AVCaptureVideoPreviewLayer?

// other code

This code imports the AVFoundation framework and sets up the captureSession and videoPreviewLayer state variables. Next, add the following code to the view’s body:

var body: some View {
ZStack {
VideoCaptureView(captureSession: $captureSession,
videoPreviewLayer: $videoPreviewLayer)
.edgesIgnoringSafeArea(.all)
BarcodeOverlay(captureSession: $captureSession)
.edgesIgnoringSafeArea(.all)
}
.onAppear(perform: startSession)
}

This code adds two subviews to the BarcodeScannerView: a VideoCaptureView and a BarcodeOverlay. The VideoCaptureView will display the camera feed and the BarcodeOverlay will be used to capture the barcode. Finally, add the following code to the view:

private func startSession() {
guard let captureDevice = AVCaptureDevice.default(for: .video) else { return }
do {
let input = try AVCaptureDeviceInput(device: captureDevice)
captureSession = AVCaptureSession()
captureSession?.addInput(input)
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
videoPreviewLayer?.videoGravity = .resizeAspectFill
videoPreviewLayer?.frame = UIScreen.main.bounds
captureSession?.startRunning()
} catch {
print(error)
}
}

This code sets up the capture session and video preview layer. Now, the BarcodeScannerView is ready to be used. To capture the barcode, create a new SwiftUI view called BarcodeOverlay and add the following code to the view:

import AVFoundation

struct BarcodeOverlay: View {
@Binding var captureSession: AVCaptureSession?

var body: some View {
ZStack {
Rectangle()
.fill(Color.clear)
.frame(width: 300, height: 200)
.overlay(
Text("Scan Barcode Here")
.foregroundColor(.white)
.font(.largeTitle)
)
.background(Color.black.opacity(0.5))
.cornerRadius(20)
.onTapGesture {
self.captureSession?.startRunning()
}
.onAppear {
self.captureSession?.stopRunning()
}
}
}
}

This code creates a ZStack with a Rectangle and Text view. The Rectangle is used to capture the barcode and the Text view is used to display a message to the user. The Rectangle is also set up with an onTapGesture and onAppear closure, which will start and stop the capture session, respectively. Finally, create a new SwiftUI view called VideoCaptureView and add the following code:

struct VideoCaptureView: UIViewRepresentable {
@Binding var captureSession: AVCaptureSession?
@Binding var videoPreviewLayer: AVCaptureVideoPreviewLayer?

func makeUIView(context: Context) -> UIView {
let view = UIView()
view.backgroundColor = .clear
return view
}

func updateUIView(_ uiView: UIView, context: Context) {
videoPreviewLayer?.removeFromSuperlayer()
if let videoPreviewLayer = videoPreviewLayer {
uiView.layer.addSublayer(videoPreviewLayer)
}
}
}

This code creates a UIViewRepresentable view that will display the camera feed. To use the BarcodeScannerView, add the following code to the ContentView:

struct ContentView: View {
var body: some View {
BarcodeScannerView()
}
}

Now, when the app is run, the BarcodeScannerView will be displayed and the user can scan barcodes.

Conclusion

Creating a custom barcode scanner with SwiftUI is a straightforward process. By setting up the AVFoundation framework, creating a BarcodeScannerView, and adding the VideoCaptureView and BarcodeOverlay subviews, developers can create a custom barcode scanner with fewer lines of code than ever before.

--

--