PlatformException при интеграции собственных экранов в модуль Flutter, но отлично работает в приложении Flutter.IOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 PlatformException при интеграции собственных экранов в модуль Flutter, но отлично работает в приложении Flutter.

Сообщение Anonymous »


В моей компании мы постепенно переносим наши собственные приложения на Flutter. На данный момент Flutter встроен как модуль в собственные приложения. Чтобы ускорить процесс и избавиться от нативных проектов, мы пытаемся показать оставшиеся нативные экраны через представление платформы Flutter и переписать их позже.

Итак, в качестве теста я запустил побочный проект, и из приложения Flutter показано, что собственный экран iOS довольно прост, и все работает так, как ожидалось. Итак, теперь я делаю то же самое в нашем собственном проекте приложения (с flutter в качестве модуля), но при навигации по представлению платформы я получаю ошибку платформы в Xcode:

flutter: [MAIN] -> PlatformDispatcher.instance.onError ⚠️: PlatformException(unregistered_view_type, виджет UIKitView пытается создать PlatformView с незарегистрированным типом: < >, если вы являетесь автором PlatformView, убедитесь, что вызывается `registerViewFactory`. См. https://docs.flutter.dev/development/pl ... orm-side-1 для получения более подробной информации. Если вы не являетесь автором PlatformView, обязательно вызовите GeneratedPluginRegistrant.register., null) флаттер: [MAIN] -> PlatformDispatcher.instance.onError ⚠️: #0 StandardMethodCodec.decodeEnvelope (пакет: flutter/src/services/message_codecs.dart:651:7) # 1 MethodChannel._invokeMethod (пакет: flutter/src/services/platform_channel.dart:322:18) #2 PlatformViewsService.initUiKitView (пакет: flutter/src/services/platform_views.dart:243:5) #3 _DarwinViewState._createNewUiKitView (пакет: flutter/src/widgets/platform_view.dart:695:36) Файлы (AppDelegate, FlutterPlatformViewFactory, FlutterPlatformView и т. д. ) одинаковы в обоих проектах. Примечание: разработчик, интегрировавший Flutter до моего прихода в компанию, начал с приложения Flutter, а затем добавил папки .android и .ios с необходимыми файлами. используется как модуль.

Есть ли принципиальная разница в регистрации вещей в двух подходах??

Большое спасибо за ваше время и помощь. Это файлы из стороннего проекта. AppDelegate:

импортировать UIKit импортировать флаттер @UIApplicationMain @objc класс AppDelegate: FlutterAppDelegate { // определяем каналы метода вар методChannel: FlutterMethodChannel? вар NativeViewerPlatformCahannel: FlutterMethodChannel? переопределить приложение func( _ приложение: UIApplication, DidFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Бул { // создаем экземпляр корневого vc как флаттер vc пусть контроллер: FlutterViewController = окно?.rootViewController как! Флаттервиевконтроллер; // инициализируем каналы метода MethodChannel = FlutterMethodChannel (имя: «test_platform_channel»,binaryMessenger: контроллер.binaryMessenger); NativeViewerPlatformCahannel = FlutterMethodChannel (имя: «native_viewer_platform_channel»,binaryMessenger: контроллер.binaryMessenger); // канал метода тестирования MethodChannel?.invokeMethod("swift_to_flutter", аргументы: ["Создан экземпляр канала метода AppDelegate"]); // устанавливаем обработчик вызова метода self.methodChannel?.setMethodCallHandler({ //[слабое я] (вызов: FlutterMethodCall, результат: @escaping FlutterResult) -> Пустота в self.methodChannel?.invokeMethod("swift_to_flutter", аргументы: ["Создан экземпляр обработчика вызова метода AppDelegate"]); переключатель (вызов.метод) { случай «тест»: self.methodChannel?.invokeMethod("swift_to_flutter", аргументы: ["Обработчик вызова метода AppDelegate: получен вызов тестового метода"]); по умолчанию: Распечатать("") } }) GeneratedPluginRegistrant.register(с: self); // MARK: NATIVE в настройке Flutter слабый регистратор var = self.registrar(forPlugin: "имя-плагина"); let Factory = DynamicNativeViewFactory(messenger: registrar!.messenger()) self.registrar(forPlugin: "")!.register( фабрика, withId: "") вернуть super.application(application, DidFinishLaunchingWithOptions: launchOptions) } } Завод:

импортировать Flutter импортировать UIKit класс DynamicNativeViewFactory: NSObject, FlutterPlatformViewFactory { частный мессенджер var: FlutterBinaryMessenger init (мессенджер: FlutterBinaryMessenger) { self.messenger = мессенджер супер.инит() } функция создания( рамка withFrame: CGRect, viewIdentifier viewId: Int64, аргументы args: Есть? ) -> FlutterPlatformView { print("DynamicNativeViewFactory инициализация") вернуть DynamicNativeView( рамка: рамка, идентификатор просмотра: идентификатор просмотра, аргументы: аргументы, binaryMessenger: мессенджер) } публичная функция createArgsCodec() -> FlutterMessageCodec & НСОбжектПротокол { вернуть FlutterStandardMessageCodec.sharedInstance() } } класс DynamicNativeView: NSObject, FlutterPlatformView { частная переменная _view: UIView = UIView(); в этом( кадр: CGRect, viewIdentifier viewId: Int64, аргументы args: Любой?, МессенджерbinaryMessenger: FlutterBinaryMessenger? ) { print("Инициализация DynamicNativeView") если let params = args как? [Строка:ЛюбойОбъект] { var screen: String = params["screen"] as! Нить; if let vc = ViewControllerGetter(rawValue: screen)?.getViewController(with: params) { _view = vc.view; } } супер.инит() } func view() -> UIView { вернуть _view } } Получатель vc:

импортировать фундамент перечисление ViewControllerGetter: String { кейс viewController случай viewController2 func getViewController (с параметрами: [String: AnyObject]?) -> UIViewController? { переключить себя { случай .viewController: если пусть vcParams = params { пусть vc = ViewController(); vc.buttonTitleA = params!["параметр 1"] as! Нить; vc.buttonTitleB = params!["параметр 2"] as! Нить; вернуть ВК } случай .viewController2: если пусть vcParams = params { пусть vc = ViewController2(); vc.buttonTitleA = params!["параметр 1"] as! Нить; vc.buttonTitleB = params!["параметр 2"] as! Нить; вернуть ВК } } вернуть ноль } } Вид платформы:
import 'dart:io'; импортируйте «dart:developer» как консоль; импортировать «пакет: флаттер/cupertino.dart»; импортировать «пакет: флаттер/материал.dart»; импортировать «пакет: flutter/services.dart»; импортировать «пакет:native_in_fluter/adaptive_platform_view.dart»; класс NativeViewer расширяет StatefulWidget { окончательный заголовок строки; конечная строка ownScreen; окончательная Map viewParams; const NativeViewer( {супер.ключ, требуется это.title, требуется this.viewParams, требуется this.nativeScreen}); @переопределить State createState() => _NativeViewerState(); } класс _NativeViewerState расширяет State { поздний канал MethodChannel; // = const MethodChannel('test_platform_channel'); @переопределить недействительный initState() { супер.initState(); канал = const MethodChannel('native_viewer_platform_channel'); Channel.setMethodCallHandler((вызов) { console.log('Набор NativeViewer setMethodCallHandler'); переключатель (вызов.метод) { случай 'swift_to_flutter': консоль.log( 'swift_to_flutter получен в NativeViewer с аргументами ${call.arguments}'); перерыв; по умолчанию: } вернуть вызов.аргументы; }); } @переопределить Сборка виджета (контекст BuildContext) { динамическая задняя кнопка = Платформа.isIOS ? CupertinoIcons.back : Icons.arrow_back; // Это используется на стороне платформы для регистрации представления. const String viewType = ''; // Передаем параметры на сторону платформы. окончательная карта CreationParams = widget.viewParams; вернуть эшафот( AppBar: AppBar( BackgroundColor: Theme.of(context).colorScheme.inversePrimary, Название: Текст( виджет.название, // стиль: const TextStyle(fontSize: 30, цвет: Colors.white), ), ведущий: IconButton( значок: Значок (backButton), // цвет: Colors.redAccent, onPressed: () { Navigator.pop(контекст); }), ), тело: AdatptivePlatformView( родной экран: виджет.nativeScreen, тип просмотра: тип просмотра, LayoutDirection: TextDirection.ltr, СозданиеПарамс: СозданиеПарамс, CreationParamsCodec: const StandardMessageCodec(), ), ); } } класс AdatptivePlatformView расширяет StatelessWidget { конечная строка ownScreen; окончательная строка viewType; окончательное динамическое созданиеParams; окончательное TextDirection? направление макета; окончательный MessageCodec? созданиеParamsCodec; const AdatptivePlatformView( {супер.ключ, требуется this.viewType, это.creationParams, это.creationParamsCodec, это.layoutDirection, требуется this.nativeScreen}); @переопределить Сборка виджета (контекст BuildContext) { вернуть Platform.isAndroid ? АндроидВью( тип просмотра: тип просмотра, LayoutDirection: TextDirection.ltr, СозданиеПарамс: СозданиеПарамс, CreationParamsCodec: const StandardMessageCodec(), ) : UiKitView( тип просмотра: тип просмотра, LayoutDirection: TextDirection.ltr, СозданиеПарамс: СозданиеПарамс, CreationParamsCodec: const StandardMessageCodec(), ); } }
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «IOS»