iOS 13 - камера зависает в VNDocumentCameraViewController

При использовании VNDocumentCameraViewController VisionKit для сканирования документов камера зависает через несколько секунд. Сканирование реализовано в ViewController, который используется в SwiftUI.

Реализация DocumentScannerViewController:

import UIKit
import VisionKit
import SwiftUI

final class DocumentScannerViewController: UIViewController, VNDocumentCameraViewControllerDelegate, UIViewControllerRepresentable {
    public typealias UIViewControllerType = DocumentScannerViewController

    public func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentScannerViewController>) -> DocumentScannerViewController {
        return DocumentScannerViewController()
    }

    public func updateUIViewController(_ uiViewController: DocumentScannerViewController, context: UIViewControllerRepresentableContext<DocumentScannerViewController>) {
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let scannerViewController = VNDocumentCameraViewController()
        scannerViewController.delegate = self as VNDocumentCameraViewControllerDelegate
        view.addSubview(scannerViewController.view)
    }

    func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
    }

    func documentCameraViewControllerDidCancel(_ controller: VNDocumentCameraViewController) {
    }

    func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFailWithError error: Error) {
    }
}

И реализация ContentView:

import SwiftUI

struct ContentView: View {
    var body: some View {
        DocumentScannerViewController()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Камера сканирования документов запускается и работает в течение короткого периода времени. Затем камера просто перестает двигаться.

Есть идеи, что вызывает такое поведение?

1 ответ

Apple предоставляет возможность использовать ViewControllers внутри представления SwiftUI с UIViewControllerRepresentable которые вы должны реализовать таким образом.

Сначала объявите свое представление следующим образом:

import SwiftUI
import UIKit
import Vision
import VisionKit

struct ScanningVNDocumentView: UIViewControllerRepresentable  {

    // implement your custom init() in case ..

    typealias UIViewControllerType = VNDocumentCameraViewController

    func makeUIViewController(context: UIViewControllerRepresentableContext<ScanningVNDocumentView>) -> VNDocumentCameraViewController {
        let viewController = VNDocumentCameraViewController()
        viewController.delegate = context.coordinator
        return viewController
    }

    func updateUIViewController(_ uiViewController: VNDocumentCameraViewController, context: UIViewControllerRepresentableContext<ScanningVNDocumentView>) {

    }

    func makeCoordinator() -> Coordinator {
    //Coordinator is Apple bridge between SwiftUI and ViewController
        return Coordinator() `// this basically call init of the UIViewControllerRepresentable above`

    }

    final class Coordinator: NSObject, VNDocumentCameraViewControllerDelegate {
        @Environment(\.presentationMode) var presentationMode

        init() {

        }
        // implement VNDocumentCameraViewControllerDelegate methods where you can dismiss the ViewController
        func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
            print("user did press save with scanned docs numbers \(scan.pageCount) ")
        }

        func documentCameraViewControllerDidCancel(_ controller: VNDocumentCameraViewController) {
    print("Did press cancel")
         }


        func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFailWithError error: Error) {
            print("Document camera view controller did finish with error ", error)

        }
    }
}

Теперь вы можете назвать свое представление так:

var body: some View {
    ScanningVNDocumentView()
}
Другие вопросы по тегам