I have a SwiftUI project in which uses UIViewControllerRepresentable
to access a DataScannerViewController
. The HomeView
displays the camera data scanner and it is the initial screen shown when the app launches. If I navigate to another view from the TabView
, and then return to the HomeView
, the data scanning stops. I believe this is because try? viewController.startScanning()
does not fire. I am unsure how to fix this issue, and I am seeking advice.
struct CameraViewRepresentable: UIViewControllerRepresentable {
@Binding var shouldStartScanning: Bool
@Binding var scanResult: String
@Binding var triggerWords: Set<String>
@ObservedObject var triggers: TriggerOptions
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIViewController(context: Context) -> DataScannerViewController {
let viewController = DataScannerViewController(
recognizedDataTypes: [.text()],
qualityLevel: .balanced,
isHighFrameRateTrackingEnabled: true,
isHighlightingEnabled: true
)
viewController.delegate = context.coordinator
try? viewController.startScanning()
return viewController
}
func recognizeTextHandler(request: VNRequest) {
let maxCandidates = 1
guard let results = request.results as? [VNRecognizedTextObservation] else {
return
}
for result in results {
guard let firstCandidate = result.topCandidates(maxCandidates).first else {
print("No Candidate Found")
continue
}
print("Candidate Found : \(firstCandidate)")
}
}
func updateUIViewController(_ viewController: DataScannerViewController, context: Context) {
if shouldStartScanning {
try? viewController.startScanning()
Task {
for await item in viewController.recognizedItems {
item.forEach { item in
switch item {
case .text(let scannedText):
triggers.triggerableCollection.forEach { trigger in
if scannedText.transcript.contains(trigger) {
triggerWords.insert(trigger)
print("Trigger Determined: \(trigger)")
}
}
default:
break
}
}
}
}
} else {
viewController.stopScanning()
shouldStartScanning = false
print("\(#file) - \(shouldStartScanning)")
}
}
class Coordinator: NSObject, DataScannerViewControllerDelegate {
var parent: CameraViewRepresentable
init(_ parent: CameraViewRepresentable) {
self.parent = parent
}
func dataScanner(_ dataScanner: DataScannerViewController, didAdd addedItems: [RecognizedItem], allItems: [RecognizedItem]) {
allItems.forEach { item in
switch item {
case .text(let scannedText):
parent.scanResult = scannedText.transcript
default:
break
}
}
}
}
}
I attempted the following...
- Added breakpoints on each function to determine when the functions were firing.
- Added a boolean check, which is set to
true
at.onAppear
of the view.
I expect that when I navigate back to the HomeView
that the scanning resumes.