首页 > 解决方案 > SwiftUI:将 MLKit 结果返回给 SwiftUI 视图不起作用

问题描述

我有一个具有以下功能的 ScannerService 类:

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
}

我从 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)
        }
        
    }
}

}

现在,我返回的是一个空字符串,而不是来自 MLKit TextRecognizer 的结果。经过一些调试,我意识到这与函数在 textRecognizer.process(visionImage) 完成之前完成有关——因为如果我在该函数中放置一个打印语句,它会显示正确的结果。

我试图放置一个 DispatchQueue.main.async,但是,我仍然无法及时获得打印结果——但是,作为线程新手,我不确定在哪里使用它。

当我单击扫描按钮时,结果返回空,但是,当我再次单击扫描按钮时,我可以在控制台中看到之前检测到的文本。

想知道在这里让 detectText 函数完成以便可以在 UI 中使用结果的最佳方法是什么。

标签: iosswiftuigoogle-mlkitdispatch-queueios-multithreading

解决方案


ML KitTextRecognizer提供异步process(_:completion:)API 和同步results(in:)API。您可以选择最适合您需要的一种。根据 ML Kit 的 API 文档,建议从主线程调用同步 API 以避免阻塞 UI。如果你从主线程调用同步 API,你会得到一个NSException.


推荐阅读