Reputation: 21
I have a ScannerService class that has the following function:
func detectText(photo: UIImage) -> String {
let textRecognizer = TextRecognizer.textRecognizer()
let visionImage = VisionImage(image: photo)
var textRecognized = ""
visionImage.orientation = photo.imageOrientation
textRecognizer.process(visionImage) { result, error in
guard error == nil, let result = result else {
// Error handling
return
}
textRecognized = result.text
}
return textRecognized
}
I am calling this function from the ScannerView:
struct ScannerView: View {
@State var scannerService = ScannerService()
@State var detectedText = ""
var body: some View {
ZStack {
ScannerViewController(scannerService: scannerService){ result in
switch result{
case .success(let photo):
if let data = photo.fileDataRepresentation(){
let result = self.scannerService.detectText(photo: UIImage(data: data)!)
print(result)
}
else{
print("Error: No image data found")
}
case .failure(let err):
print(err.localizedDescription)
}
}
VStack {
Spacer()
Button(action: {
self.scannerService.capturePhoto()
}, label: {
Image(systemName: "circle")
.font(.system(size: 72))
.foregroundColor(.white)
})
.padding(.bottom)
}
}
}
}
Right now, I am returned an empty string rather than the result from the MLKit TextRecognizer. After some debugging, I realized this has to do with the function completing before textRecognizer.process(visionImage) finishes – since if I put a print statement in that function, it displays the correct result.
I have tried to put a DispatchQueue.main.async, however, I am still unable to get the printed result in time – however, being new to threading, I am unsure where to use it.
When I click the scan button, the result returns empty, however, when I click the scan button again I can see in the console, the previous text that was detected.
Wondering what is the best way here to let the detectText function complete so that the result can be used in the UI.
Upvotes: 0
Views: 218
Reputation: 882
ML Kit's TextRecognizer
provides both an async process(_:completion:)
API and a sync results(in:)
API. You can choose the one that best fits your need. Per ML Kit's API documentation, it is advised to call the sync API off the main thread to avoid blocking the UI. If you call the sync API from the main thread, you will get an NSException
.
Upvotes: 0