For a Flutter project I need to call a method channel in order to run platform specific code for iOS devices.
I would like to provide the VNDocumentCameraViewController of the VisionKit framework and in order to send the image path back to Flutter, I need to register a completion handler that runs after the VNDocumentCameraViewController is dismissed.
Therefore, I have a FlutterChannelManager that initializes the custom class DocumentCameraHandler which conforms to VNDocumentCameraViewController and VNDocumentCameraViewControllerDelegate and provides a handler for the result.
The VNDocumentCameraViewController is presented as expected and I can scan documents and everything but when the view controller is dismissed, the VNDocumentCameraViewControllerDelegate methods are somehow not called and my app throws the following error on the main thread:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x1f9400aa8)
These are the relevant classes in my project:
@available(iOS 13.0, *)
class FlutterChannelManager: NSObject {
unowned let flutterViewController: UIViewController
init(flutterViewController: UIViewController) {
self.flutterViewController = flutterViewController
}
func setup(){
let documentCamera = buildDocumentCamera()
self.flutterViewController.present(documentCamera, animated: true)
}
func buildDocumentCamera() -> UIViewController {
return DocumentCameraHandler { (image) in
self.flutterViewController.dismiss(animated: true, completion: nil)
if let image = image {
print("SUCCESS")
} else {
print("ERROR")
}
}
}
}
@available(iOS 13.0, *)
class DocumentCameraHandler: VNDocumentCameraViewController, UINavigationControllerDelegate, VNDocumentCameraViewControllerDelegate {
var handler: ((_ image: UIImage?) -> Void)?
convenience init(handler: @escaping (_ image: UIImage?) -> Void) {
self.init()
self.delegate = self
self.handler = handler
}
func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
handler?(scan.imageOfPage(at: 0))
}
func documentCameraViewControllerDidCancel(_ controller: VNDocumentCameraViewController) {
handler?(nil)
}
func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFailWithError error: Error) {
handler?(nil)
}
}