Barcodes sind ueberall, und dank Apples umfangreicher Frameworks haben wir alles, um die Barcode-Verarbeitung zu einer einfachen Aufgabe zu machen. Dieser Artikel bietet alles, was noetig ist, um Barcode-Scanning in eine iOS-Anwendung auf SwiftUI-Basis zu integrieren.
Neben SwiftUI werden in diesem Tutorial zwei weitere Frameworks verwendet.
Erstens gibt es AVFoundation, das in Apples Entwicklerdokumentation wie folgt beschrieben wird:
Work with audiovisual assets, control device cameras, process audio, and configure system audio interaction.
Zweitens werden wir das Vision-Framework verwenden:
Apply computer vision algorithms to perform a variety of tasks on input images and video.
Dieser Artikel fuehrt durch alle Schritte, um die relevanten Klassen zu verbinden und eine SwiftUI-Anwendung zu erstellen, die den gescannten Barcode anzeigt.
Der Xcode-Workspace mit der voll funktionsfaehigen Anwendung kann hier heruntergeladen werden.
Sieh die App in Aktion:
Anwendungsarchitektur
Zuerst gebe ich einen kurzen Ueberblick ueber alle in dieser Anwendung erstellten Klassen.
Unten ist ein einfaches Klassendiagramm, das alle relevanten Elemente zeigt.

App: Dies ist die grundlegende App-Vorlage, wie sie von Xcode erstellt wurde, und wurde unveraendert belassen.
ContentView: Enthaelt die ScannerView und den Text, der das gescannte Barcode-Ergebnis anzeigt. Sie hat eine @State-Variable, die an die ScannerView (siehe unten) uebergeben wird und den Text automatisch aktualisiert, wenn sie sich aendert. Man muss SwiftUI einfach lieben.
ScannerView: Es gibt keine native SwiftUI-View, die das tut, was wir wollen, also muessen wir eine UIView, die den Video-Feed unserer Kamera zeigt, in ein UIViewRepresentable einwickeln, wie ich in meinem Artikel “Using UIView and UIViewController in SwiftUI” erklaert habe. Diese View stellt das gescannte Ergebnis ueber ihre @Binding-Variable ihrer uebergeordneten View zur Verfuegung.
CameraView: Dies ist die UIView, die von der oben genannten ScannerView umschlossen wird. Sie umhuellt ein AVCaptureVideoPreviewLayer, das die Ebene ist, die zeigt, was von der eingebauten Kamera des iPhones oder iPads erfasst wird.
Coordinator: Diese Klasse ist Teil des UIViewRepresentable und erledigt den Grossteil der Arbeit. Zuerst fragen wir nach der Kameraberechtigung, dann richten wir eine Pipeline ein, um die Kameraausgabe zu erfassen, und schliesslich fuehren wir sie dem Code zu, der die Barcode-Erkennung durchfuehrt.
Nach Kameranutzung fragen
Um die Kamera zu verwenden, muss zuerst die “Camera Usage Description” in der Info.plist gesetzt werden.

Spaeter, wenn die App zum ersten Mal gestartet wird, erscheint Folgendes und fragt den Benutzer um Erlaubnis, die Kamera zu verwenden.

Im Code fragen wir mit folgendem Befehl nach der Berechtigung:
AVCaptureDevice.requestAccess(for:.video)Einrichten des Kamera-Feeds
Jetzt, da wir Zugriff auf die Kamera haben, koennen wir die Pipeline zum Abrufen der Video-Frames einrichten, die dann in den Algorithmus zur Extraktion der Barcode-Informationen eingespeist werden koennen.
Dies sind die Elemente, die wir benoetigen, zusammen mit einer Beschreibung von Apple:
AVCaptureDevice- A device that provides input (such as audio or video) for capture sessions and offers controls for hardware-specific capture features.
AVCaptureDeviceInput- A capture input that provides media from a capture device to a capture session.
AVCaptureSession- An object that manages capture activity and coordinates the flow of data from input devices to capture outputs.
AVCaptureVideoDataOutput- A capture output that records video and provides access to video frames for processing.

Waehrend die AVCaptureSession zentral fuer das Sammeln und Verarbeiten der notwendigen Video-Frames ist, interessieren wir uns letztendlich fuer die Video-Frames selbst, um die Barcode-Erkennungsalgorithmen darauf auszufuehren.
Die AVCaptureVideoDataOutput hat einen Delegaten, der die erfasste Ausgabe und den Puffer mit den Samples empfaengt.
Unser Coordinator wird als dieser Delegat fungieren, indem er von AVCaptureVideoDataOutputSampleBufferDelegate erbt und captureOutput(_:didOutput:from:) implementiert.
Verarbeitung des erfassten Bildes
Ein weiterer Schritt ist noetig, um die Barcode-Informationen zu erhalten: die Verarbeitung der von der Handykamera empfangenen Bilder.
Zwei Klassen sind hauptsaechlich dafuer verantwortlich:
VNImageRequestHandler- An object that processes one or more image analysis requests pertaining to a single image.
VNDetectBarcodesRequest- An image analysis request that finds and recognises barcodes in an image.
So arbeiten sie zusammen:

Bei der Instanziierung der VNDetectBarcodesRequest muessen wir einen Handler bereitstellen, der das Ergebnis verarbeitet.
let request = VNDetectBarcodesRequest(completionHandler: self.barcodeRequestHandler)Dieser Handler empfaengt dann das beobachtete Ergebnis, das wir weiterverarbeiten und den endgueltigen String extrahieren koennen:
func barcodeRequestHandler(request: VNRequest, error: Error?) {
guard let results = request.results as? [VNBarcodeObservation],
let payloadStringValue = results.last?.payloadStringValue else {
return
}
self.scanResult = payloadStringValue
}Fazit
In diesem Beitrag habe ich dargelegt, was noetig ist, um eine SwiftUI-App zu erstellen, die Barcodes scannt.
Der Xcode-Workspace mit der voll funktionsfaehigen Anwendung kann hier heruntergeladen werden.