简体   繁体   中英

SwiftUI: Return MLKit result to SwiftUI view not working

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM