Speed up MatrixScan Batch integration with Agent Skills
Install the official skill to help your coding agent (Claude Code, Codex, Cursor, etc.) integrate, debug, and customize MatrixScan Batch on iOS following Scandit's recommended patterns. More info →
Run this in a terminal in your project directory, then follow the instructions to select your coding agent.
npx skills add https://github.com/scandit/skills --skill matrixscan-batch-iosYour coding agent loads the skill automatically based on your prompt; to invoke it explicitly, call /matrixscan-batch-ios followed by your task.
Get Started With SwiftUI
In this guide you will learn step-by-step how to add MatrixScan to your application using SwiftUI.
The general steps are:
- Create a UIViewController: Implement the MatrixScan logic following the main Get Started guide
- Create a SwiftUI wrapper: Use
UIViewControllerRepresentableto integrate theUIViewController - Use in your SwiftUI app: Add the SwiftUI view to your app's view hierarchy
The core MatrixScan implementation (data capture context, settings, camera setup, etc.) remains the same as described in the main guide.
Create a UIViewController for MatrixScan
To integrate the Scandit Data Capture SDK with SwiftUI, you'll need to create a UIViewController that handles the MatrixScan functionality. This follows the same implementation as described in the main Get Started guide.
Create a MatrixScanViewController class that implements all the steps from the UIKit guide:
import ScanditBarcodeCapture
import UIKit
class MatrixScanViewController: UIViewController {
private var context: DataCaptureContext!
private var camera: Camera?
private var barcodeBatch: BarcodeBatch!
private var captureView: DataCaptureView!
private var overlay: BarcodeBatchBasicOverlay!
override func viewDidLoad() {
super.viewDidLoad()
setupRecognition()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
barcodeBatch.isEnabled = true
camera?.switch(toDesiredState: .on)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
barcodeBatch.isEnabled = false
camera?.switch(toDesiredState: .off)
}
func setupRecognition() {
// Follow the implementation from the Get Started guide:
// 1. Create data capture context
// 2. Configure the Barcode Batch Mode
// 3. Use the built-in camera
// 4. Visualize the scan process
// 5. Provide feedback
}
}
extension MatrixScanViewController: BarcodeBatchBasicOverlayDelegate {
func barcodeBatchBasicOverlay(_ overlay: BarcodeBatchBasicOverlay,
brushFor trackedBarcode: TrackedBarcode) -> Brush? {
// Return a custom Brush based on the tracked barcode.
}
func barcodeBatchBasicOverlay(_ overlay: BarcodeBatchBasicOverlay,
didTap trackedBarcode: TrackedBarcode) {
// Handle barcode tap
// See the main Get Started guide
}
}
Create a SwiftUI View using UIViewControllerRepresentable
Now create a SwiftUI wrapper that integrates the UIViewController into your SwiftUI app:
import SwiftUI
import UIKit
struct MatrixScanRepresentable: UIViewControllerRepresentable {
typealias UIViewControllerType = MatrixScanViewController
func makeUIViewController(context: Context) -> MatrixScanViewController {
return MatrixScanViewController()
}
func updateUIViewController(_ uiViewController: MatrixScanViewController, context: Context) {
// Update the view controller if needed
}
}
Use the SwiftUI View in Your App
Finally, use the MatrixScanRepresentable in your SwiftUI app:
import SwiftUI
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
MatrixScanRepresentable()
}
}
}
Or within another SwiftUI view:
struct ContentView: View {
var body: some View {
NavigationView {
MatrixScanRepresentable()
.navigationTitle("MatrixScan")
}
}
}
Alternative: Using UIViewRepresentable
As an alternative to wrapping a UIViewController, you can implement the MatrixScan functionality directly using UIViewRepresentable. This approach uses a Coordinator to hold the SDK objects, ensuring they are created once and persist across SwiftUI updates:
import ScanditBarcodeCapture
import SwiftUI
struct MatrixScanView: UIViewRepresentable {
let onBarcodeBatchUpdated: ([TrackedBarcode]) -> Void
func makeCoordinator() -> Coordinator {
Coordinator()
}
func makeUIView(context: Context) -> UIView {
let coordinator = context.coordinator
coordinator.onBarcodesUpdated = onBarcodeBatchUpdated
if let camera = Camera.default {
// Apply recommended camera settings
let cameraSettings = BarcodeBatch.recommendedCameraSettings
camera.apply(cameraSettings)
// Turn on the camera
coordinator.dataCaptureContext.setFrameSource(camera)
camera.switch(toDesiredState: .on)
coordinator.camera = camera
}
// Enable Barcode Batch
coordinator.barcodeBatch.isEnabled = true
// Create the capture view
let captureView = DataCaptureView(context: coordinator.dataCaptureContext, frame: .zero)
captureView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// Create the overlay
coordinator.overlay = BarcodeBatchBasicOverlay(barcodeBatch: coordinator.barcodeBatch, view: captureView, style: .frame)
return captureView
}
func updateUIView(_ uiView: UIView, context: Context) {
context.coordinator.onBarcodesUpdated = onBarcodeBatchUpdated
}
static func dismantleUIView(_ uiView: UIView, coordinator: Coordinator) {
coordinator.barcodeBatch.isEnabled = false
coordinator.camera?.switch(toDesiredState: .off)
}
class Coordinator: NSObject, BarcodeBatchListener {
let dataCaptureContext: DataCaptureContext
let barcodeBatch: BarcodeBatch
var overlay: BarcodeBatchBasicOverlay?
var camera: Camera?
var onBarcodesUpdated: (([TrackedBarcode]) -> Void)?
override init() {
// Create the data capture context
DataCaptureContext.initialize(licenseKey: "-- ENTER YOUR SCANDIT LICENSE KEY HERE --")
dataCaptureContext = DataCaptureContext.shared
// Configure barcode batch settings
let settings = BarcodeBatchSettings()
// ...
// Create barcode batch mode
barcodeBatch = BarcodeBatch(context: dataCaptureContext, settings: settings)
super.init()
barcodeBatch.addListener(self)
}
nonisolated func barcodeBatch(_ barcodeBatch: BarcodeBatch,
didUpdate session: BarcodeBatchSession,
frameData: FrameData) {
let trackedBarcodes = session.trackedBarcodes.values.map { $0 }
DispatchQueue.main.async {
self.onBarcodesUpdated?(trackedBarcodes)
}
}
}
}
You can then use this view directly in your SwiftUI app:
struct ContentView: View {
var body: some View {
NavigationView {
MatrixScanView { trackedBarcodes in
// Handle the tracked barcodes
}
.navigationTitle("MatrixScan")
}
}
}