[Flutter Platform Views]Camera feed not shown in iOS with DataScannerViewController

49 views Asked by At

I've use Flutter Plaltform View to embed Native iOS view into Flutter. Native iOS view is associated with DataScannerViewController which come along with Vision Kit. But when starting the flutter app, the view is white. But I ran the same code in native iOS. It worked fine. My Code work is as bellow. is there anyway to over come this issue?

//Flutter Code@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const UiKitView(viewType: 'ARViewContainer'));
}

//Code in Swift

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
\_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: \[UIApplication.LaunchOptionsKey: Any\]?
) -\> Bool {
GeneratedPluginRegistrant.register(with: self)
weak var registrar = self.registrar(forPlugin: "my-views")
let cealQrViewfactory = ARViewContainerNativeViewFactory(messenger: registrar!.messenger())
let viewRegistrar = self.registrar(forPlugin: "\<my-views\>")!
viewRegistrar.register (cealQrViewfactory,
withId: "ARViewContainer")
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

import UIKit
import VisionKit
import AVKit

class ARViewContainerNativeViewFactory: NSObject, FlutterPlatformViewFactory {
private var messenger: FlutterBinaryMessenger

    init (messenger: FlutterBinaryMessenger){
        self.messenger = messenger
        super.init ()
    }
    
    public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
        return FlutterStandardMessageCodec.sharedInstance()
    }
    
    
    func create( withFrame frame: CGRect, viewIdentifier viewId: Int64,
                 arguments args: Any?) -> FlutterPlatformView{
        return ARViewContainerNativeView(frame: frame, viewIdentifier: viewId, arguments: args, binaryMessenger: messenger)
    }

}

class ARViewContainerNativeView: NSObject, FlutterPlatformView {
private var \_view: UIView
let channel: FlutterMethodChannel

    init( frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?,
          binaryMessenger messenger: FlutterBinaryMessenger?
    ) {
        let argumentsDictionary = (args as? Dictionary<String, Any>) ?? [:]
        _view = UIView()
        channel = FlutterMethodChannel(name: "ARContainerView/\(viewId)", binaryMessenger: messenger!)
    
        super.init ()
        createNativeView(view: _view, productList: argumentsDictionary)
    }
    
    func view() -> UIView {
        return _view
    }
    
    func createNativeView(view _view: UIView, productList :Dictionary<String, Any>) {
        let vc = UIStoryboard(name: "MatrixBarcodeStory", bundle: nil).instantiateViewController(withIdentifier: "MatrixBarcodeVC") as! MatrixBarcodeVC
        vc.view.frame = _view.bounds
        _view.addSubview(vc.view)
    }
    
    public func sendFromNative(_ text: String) {
      channel.invokeMethod("sendFromNative", arguments: text)
    }

}

class MatrixBarcodeVC: UIViewController, DataScannerViewControllerDelegate {

    let dataScannerVC = DataScannerViewController(
        recognizedDataTypes: [.barcode()],
        qualityLevel: .balanced,
        recognizesMultipleItems: true,
        isGuidanceEnabled: true,
        isHighlightingEnabled: false
    )
    
    private var isScannerAvailable: Bool {
        DataScannerViewController.isAvailable && DataScannerViewController.isSupported
    }
    
    var itemHighlightViews: [RecognizedItem.ID: UIView] = [:]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        dataScannerVC.delegate = self
        dataScannerVC.view.frame = self.view.bounds
        self.view.addSubview(dataScannerVC.view)
        try? self.dataScannerVC.startScanning()
    }

}

//DataScannerViewControllerDelegate
extension MatrixBarcodeVC{

    func dataScanner(_ dataScanner: DataScannerViewController, didAdd addedItems: [RecognizedItem], allItems: [RecognizedItem]) {
        for item in addedItems {
            switch item {
            case .barcode(_):
                let newView = newHighlightView(item: item)
                itemHighlightViews[item.id] = newView
                dataScanner.overlayContainerView.addSubview(newView)
                print("item \(item)")
            default:
                break
            }
        }
    }
    
    func dataScanner(_ dataScanner: DataScannerViewController, didUpdate updatedItems: [RecognizedItem], allItems: [RecognizedItem]) {
        for item in updatedItems {
            if let view = itemHighlightViews[item.id] {
                updateHighlightView(item: item, view: view)
            }
        }
    }
    
    func dataScanner(_ dataScanner: DataScannerViewController, didRemove removedItems: [RecognizedItem], allItems: [RecognizedItem]) {
        for item in removedItems {
            if let view = itemHighlightViews[item.id] {
                itemHighlightViews.removeValue(forKey: item.id)
                view.removeFromSuperview()
                print("didRemovedItems \(removedItems)")
            }
        }
    }
    
    func updateHighlightView(item:RecognizedItem, view:UIView){
        var rect = CGRect(origin: item.bounds.bottomLeft,
                          size: CGSize(width: item.bounds.topRight.x - item.bounds.topLeft.x,
                                       height: item.bounds.topRight.y - item.bounds.bottomRight.y))
        view.frame = rect
    }
    
    func dataScanner(_ dataScanner: DataScannerViewController, didTapOn item: RecognizedItem) {
        print("didTapOn \(item)")
    }
    
    func dataScanner(_ dataScanner: DataScannerViewController, becameUnavailableWithError error: DataScannerViewController.ScanningUnavailable){
        print("became unavailable with error \(error.localizedDescription)")
    }

}

//MARK: Helping Methods
extension MatrixBarcodeVC{

    func newHighlightView(item:RecognizedItem) -> UIView{
        print("height :: \(item.bounds.topRight.y - item.bounds.bottomRight.y)")
        switch item {
        case .barcode(let barcode):
            print(barcode.payloadStringValue)
        default:
            break
        }
        return UIView()
    }
}
0

There are 0 answers