In this tutorial, we’ll use Xcode, SwiftUI, and the Scanbot Barcode Scanner SDK to create a powerful scanning app for extracting data from barcodes and QR codes.


We’ll achieve this in three easy steps:
- Preparing the project
- Setting up the app entry point
- Implementing the barcode scanner view
All you need is a Mac with the latest version of Xcode and a test device, since we’ll need to use the camera.
Want to see the final code right away? Click here.
ContentView.swift:
import SwiftUI
import ScanbotBarcodeScannerSDK
struct ContentView: View {
let configuration: SBSDKUI2BarcodeScannerScreenConfiguration = {
let config = SBSDKUI2BarcodeScannerScreenConfiguration()
let usecase = SBSDKUI2MultipleScanningMode()
usecase.arOverlay.visible = true
config.useCase = usecase
return config
}()
var body: some View {
SBSDKUI2BarcodeScannerView(
configuration: configuration,
onSubmit: { (result: SBSDKUI2BarcodeScannerUIResult?) in
if let result = result {
guard !result.items.isEmpty else {
print("No barcode found")
return
}
for barcodeItem in result.items {
let format = barcodeItem.barcode.format.name
let value = barcodeItem.barcode.textWithExtension
print("\(format): \(value)")
}
}
},
onCancel: {
// Handle the user tapping the 'Cancel' button
},
onError: { error in
// Handle errors
}
)
}
}
#Preview {
ContentView()
}
Step 1: Prepare the project
Open Xcode and create a new iOS App project. Name the project (e.g., “SwiftUI Barcode Scanner”), choose SwiftUI as the interface, and Swift as the language.
After opening your project, go to File > Add Package Dependencies… and add the Scanbot Barcode Scanner SDK package for the Swift Package Manager.
Now open your Main App Target’s Info tab and add a Privacy – Camera Usage Description key with a value such as “Grant camera access to scan barcodes”.
Step 2: Set up the app entry point
Open SwiftUI_Barcode_ScannerApp.swift, import the Scanbot Barcode Scanner SDK, and implement the init()
method to set the SDK’s license key.
import SwiftUI
// Import the SDK
import ScanbotBarcodeScannerSDK
@main
struct iOS_Swift_UI_Barcode_ScannerApp: App {
// Set the license key
init() {
//Scanbot.setLicense("<YOUR_LICENSE_KEY_HERE>")
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
If you have a license key, you can uncomment the code and replace <YOUR_LICENSE_KEY_HERE>
with your actual key. Otherwise, leave the code as is. The SDK will then run in trial mode for 60 seconds per seconds.
Step 3: Implement the barcode scanner view
Open ContentView.swift and once again import the SDK.
import ScanbotBarcodeScannerSDK
Then, inside struct ContentView: View {}
and above var body: some View {}
, add the configuration for single-barcode scanning.
let configuration: SBSDKUI2BarcodeScannerScreenConfiguration = {
let config = SBSDKUI2BarcodeScannerScreenConfiguration()
let usecase = SBSDKUI2SingleScanningMode()
config.useCase = usecase
return config
}()
Then replace the boilerplate code inside var body: some View {}
with the barcode scanner view and pass the configuration.
var body: some View {
SBSDKUI2BarcodeScannerView(
configuration: configuration,
onSubmit: { result in
// Handle the scanned barcode results
},
onCancel: {
// Handle the user tapping the 'Cancel' button
},
onError: { error in
// Handle errors
}
)
}
In this tutorial, we’re going to print the format and value of the first barcode recognized in the camera stream to the console.
onSubmit: { (result: SBSDKUI2BarcodeScannerUIResult?) in
if let result = result {
guard let barcodeItem = result.items.first else {
print("No barcode found")
return
}
let format = barcodeItem.barcode.format.name
let value = barcodeItem.barcode.textWithExtension
print("\(format): \(value)")
}
},
To make sure you only scan the barcode you want, you can make use of the confirmation dialogue included in the SDK’s RTU UI components. To use it, simply enable the required component in the usecase
configuration.
let configuration: SBSDKUI2BarcodeScannerScreenConfiguration = {
let config = SBSDKUI2BarcodeScannerScreenConfiguration()
let usecase = SBSDKUI2SingleScanningMode()
// Enable the confirmation dialogue
usecase.confirmationSheetEnabled = true
config.useCase = usecase
return config
}()
Now our iOS Barcode Scanner app is ready. Build and run the app and give it a try!

Optional: Implement multi-barcode scanning with an AR overlay
As it is now, our app prints the value of the first scanned barcode to the console. But we can also scan multiple barcodes at once. As an added bonus, we can also display the barcodes’ values right in the scanning screen while giving users the option to tap on any barcode to add it to a results sheet.
To achieve this, simply replace the single-barcode scanning configuration in ContentView.swift with the multi-scanning one and also enable the AR overlay:
let configuration: SBSDKUI2BarcodeScannerScreenConfiguration = {
let config = SBSDKUI2BarcodeScannerScreenConfiguration()
let usecase = SBSDKUI2MultipleScanningMode()
usecase.arOverlay.visible = true
config.useCase = usecase
return config
}()
You can change the results handling to reflect that multiple barcodes’ values should be printed to the console:
if let result = result {
guard !result.items.isEmpty else {
print("No barcode found")
return
}
for barcodeItem in result.items {
let format = barcodeItem.barcode.format.name
let value = barcodeItem.barcode.textWithExtension
print("\(format): \(value)")
}
}
Your final ContentView.swift will then look something like this:
import SwiftUI
import ScanbotBarcodeScannerSDK
struct ContentView: View {
let configuration: SBSDKUI2BarcodeScannerScreenConfiguration = {
let config = SBSDKUI2BarcodeScannerScreenConfiguration()
let usecase = SBSDKUI2MultipleScanningMode()
usecase.arOverlay.visible = true
config.useCase = usecase
return config
}()
var body: some View {
SBSDKUI2BarcodeScannerView(
configuration: configuration,
onSubmit: { (result: SBSDKUI2BarcodeScannerUIResult?) in
if let result = result {
guard !result.items.isEmpty else {
print("No barcode found")
return
}
for barcodeItem in result.items {
let format = barcodeItem.barcode.format.name
let value = barcodeItem.barcode.textWithExtension
print("\(format): \(value)")
}
}
},
onCancel: {
// Handle the user tapping the 'Cancel' button
},
onError: { error in
// Handle errors
}
)
}
}
#Preview {
ContentView()
}
Now build and run the app again to test your multi-barcode scanner.

If you’re in need of some barcodes, we’ve got you covered:

Conclusion
🎉 Congratulations! You’ve successfully built a powerful iOS barcode scanning app in SwiftUI!
This is just one of the many scanner configurations the Scanbot SDK has to offer – take a look at the RTU UI documentation and API references to learn more.
Should you have questions or run into any issues, we’re happy to help! Just shoot us an email via tutorial-support@scanbot.io.
Happy scanning! 🤳
Building an enterprise-grade barcode scanning app for real-world scenarios
As you build your iOS barcode scanning app, consider technical and strategic insights to boost performance, reliability, and long-term value.
Differences between native APIs and commercial SDKs
As a developer, you might wonder about Apple’s native frameworks – AVFoundation or Vision – when it comes to scanning barcodes. AVFoundation, a lightweight and flexible lower-level tool, supports basic linear barcode scanning but lacks advanced features like a scan UI or support for damaged or complex barcodes. The Vision framework integrates with Core ML and offers modern APIs; however, it doesn’t fully support multi-barcode scanning or decoding in tough conditions. In contrast, commercial barcode scanning SDKs are designed for production, offering superior accuracy, better low-light performance, and broad barcode format support.
Performance in real-world conditions
Barcode scanning isn’t always done in ideal conditions. Therefore, benchmark your solution against lighting, barcode quality, distance, and motion. Commercial solutions consistently outperform native APIs – especially when dealing with low-light environments, fast-moving barcodes, or damaged labels. Where native tools might struggle or fail, specifically trained algorithms offer fast, reliable detection, making them a safer bet for commercial or mission-critical uses.
Understanding cost and licensing trade-offs
Another important factor to consider is the cost of integration. This investment is often offset by faster development and lower long-term maintenance. Building a barcode solution from scratch with native APIs or open-source libraries might seem cheap at first, but it often carries hidden costs: troubleshooting, custom parsing logic, and handling edge cases. For businesses aiming for quick deployment and reliable scaling, a commercial SDK is often more economical in the long run.
Working with industry standards
For industries like retail, healthcare, and logistics, simply reading a barcode isn’t enough – you’ve got to interpret the structured data within. Your solution should support industry standards such as GS1 and HIBC, enabling your app to parse and extract critical fields like product IDs, expiration dates, and batch numbers directly from the scan result. This semantic decoding is crucial for regulatory compliance or backend integration.
Building for offline use
A robust scanning app should function reliably even without an internet connection and process barcode data directly on the device. To prevent data loss during connectivity issues, think about locally queuing scan results in encrypted storage and syncing them to your server once the connection is restored. Exponential backoff and retry queues can boost reliability and user trust.
Prioritizing security and privacy
Security is another key consideration, especially when working with third-party libraries. Don’t transmit any data externally unless you actually send it. Further enhance security by encrypting all local scan data and using secure transfer protocols when syncing to the cloud.
Enhancing accessibility and user experience
Inclusive design benefits everyone. To improve accessibility, ensure your scanner works well with the VoiceOver screen reader, supports large fonts, and provides haptic or audio feedback to signal successful scans. These features not only improve app usability for people with disabilities but also boost overall user satisfaction.
Troubleshooting common issues
Finally, here are a few quick tips for tackling common integration challenges: If your scanner doesn’t activate, ensure camera permissions are correctly set in your app’s Info.plist. If scans return no results, double-check the desired barcode formats are enabled in the SDK configuration. App startup crashes often stem from SDK initialization issues or an invalid license – review the setup instructions and license validation logic to ensure everything is correct.
By considering these advanced topics, you’re not just building a barcode scanner, but a reliable, secure, and user-friendly solution that’s ready for real-world deployment. Whether you’re shipping an enterprise app or a lightweight utility, these best practices will help you deliver greater value to your users.