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()
}
}