Flutter: Complemento de interacción nativa y Flutter recomendado oficialmente Pigeon

Introducción al complemento

Una herramienta de generación de código que hace que Flutterla comunicación con la plataforma host sea más segura, sencilla y rápida. A través Dartde la entrada se genera el código de la plantilla común a ambos extremos, y el nativo solo necesita reescribir la interfaz en la plantilla, sin Method Channelnecesidad de implementación de gestión. Los parámetros se pueden generar sincrónicamente a través de plantillas. Esto es realmente conveniente Para las tres formas del sistema, puede consultar este artículo (Tres formas de Flutter y comunicación nativa ).

Información del complemento

Dirección del complemento: pub.flutter-io.cn/packages/pi…

Versión del complemento: paloma: 3.0.3

uso de complementos

Preparativos para Flutter

Cree una carpeta de palomas fuera del directorio lib del proyecto Flutter y cree schema.dart en la carpeta de palomas

Debido a que actualmente es una combinación de nativo y Flutter, necesito obtener información de usuario y localHost de nativo, por lo que el código de schema.dart es el siguiente

/// Description : 定义与原生通信--通过自动生成减少手写代码量
/// 请求参数和返回结果都必需是类结构 否则无法生成文件
/// - Flutter 调用 Native 方法 ( @HostApi() )
/// - Native 调用 Flutter 方法 ( @FlutterApi() )

///Flutter 调用原生代码
@HostApi()
abstract class UserInfoApi {
  ///获取用户信息
  UserInfo getUserInfo();
  ///获取LocalHost用于抓包
  String getLocalHost();
}

///用户信息实体类
class UserInfo {
  String? userId;
  String? realName;
  String? phone;
  String? headImg;
}
复制代码

comando usado

命令拆解:
①` flutter pub run pigeon`  
生成代码的命令

②` --input pigeons/schema.dart `
指定生成代码的输入`dart`文件

③ `--dart_out lib/schema.dart `
指定输出生成`dart`文件的目录文件

④ `--objc_header_out ios/Flutter/FlutterPluginRegistrant/Classes/schema.h  `
指定要生成的`iOS`的`.h`文件路径

⑤ `--objc_source_out ios/Flutter/FlutterPluginRegistrant/Classes/schema.m  `
指定要生成的`iOS`的`.m`文件路径

⑥ `--java_out android/Flutter/src/main/java/io/flutter/plugins/Schema.java `
指定要生成的`Android`的`.java`文件路径

⑦  `--java_package "io.flutter.plugins`
指定`Android`的包名,在`android/src/main/`下的`AndroidManifest.xml`里的`package`

⑧ `--objc_prefix Z`(可选)指定生成OC文件的前缀为Z,前缀自己定义为自己的。

复制代码

En el directorio del proyecto ~/flutter_pigeon_plugin, es demasiado problemático ejecutar el comando directamente, aquí creé un script, y es suficiente ejecutar el script directamente cada vez que hay una actualización.

Crear guión

Este script está escrito de acuerdo con el comando anterior, y este también es el script run pigeon.sh creado en la carpeta de palomas.

flutter pub run pigeon \
  --input pigeons/schema.dart \
  --dart_out lib/schema.dart \
  --objc_header_out ios/Flutter/FlutterPluginRegistrant/Classes/schema.h \
  --objc_source_out ios/Flutter/FlutterPluginRegistrant/Classes/schema.m \
  --java_out android/Flutter/src/main/java/io/flutter/plugins/Schema.java \
  --java_package "io.flutter.plugins"

  # 点击绿色三角形按钮,或者选择文件右键选择运行此文件,开启运行以上脚本文件,
  # 然后会自动生产跨端通信的Android文件(Java文件)和iOS文件(Object_C)
 No newline at end of file
复制代码

Este es el archivo que se genera automáticamente después de ejecutar el script

截屏2022-05-14 17.44.11.png

截屏2022-05-14 17.44.41.png

截屏2022-05-14 17.46.14.png

¿Cómo comunicarse?

Por ejemplo: no escribí dos métodos arriba, entonces si quiero capturar paquetes, necesito configurarlo en la ip de Mac

Código lateral de aleteo

if (!kReleaseMode){
  UserInfoApi().getLocalHost().then((value) {
    if(value.isNotEmpty){
      (_dio!.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (HttpClient client) {
        client.findProxy = (uri) {
          return "PROXY $value:8888";
        };
      };
    }
  });
}
复制代码

código nativo

En primer lugar, se debe introducir el módulo Flutter en el proyecto nativo, que no se explicará aquí. Creó una clase que hereda de FlutterViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [GeneratedPluginRegistrant registerWithRegistry:self.engine];
    //这里是需要传入一个对象的
    UserInfoApiSetup(self.binaryMessenger, [UserInfoAPI new]);
}

- (void)viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];
    self.navigationController.navigationBarHidden = YES;
}

- (void)viewWillDisappear:(BOOL)animated {

    [super viewWillDisappear:animated];
    self.navigationController.navigationBarHidden = NO;
}
复制代码

También debe crear una clase que siga el protocolo UserInfoApi e implemente los métodos del protocolo.

@interface UserInfoAPI : NSObject<UserInfoApi>

@end

@implementation UserInfoAPI
- (nullable UserInfo *)getUserInfoWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
    UserInfo *userInfo = [[UserInfo alloc] init];
    return userInfo;
}

- (nullable NSString *)getLocalHostWithError:(FlutterError * _Nullable * _Nonnull)error {
    return @"10.210.3.16";
}
@end
复制代码

La página Flutter vuelve a la página nativa

De esta manera, Flutter puede llamar al método nativo. Generalmente, saltamos a la página de Flutter. Si queremos volver a la página nativa, también podemos lograrlo. Al llamar al método nativo, regresa el procesamiento nativo, como el El lado de iOS puede lograr esto.

if ([mthodStr isEqualToString:@"closeFlutterVC"]) {
   //调用popViewControllerAnimated
}
复制代码

Flutter返回Android端则直接可以调用方法完成

SystemNavigator.pop();
复制代码

原生进入Flutter页面

//这里可以传入要进入flutter页面的路由
TestViewController *flutterVC = [[IAskFlutterViewController alloc] initWithProject:nil initialRoute:@"" nibName:nil bundle:nil];[self.navigationController pushViewController:flutterVC animated:YES];
复制代码

Android端其实也是同理,实现getInitialRoute方法,返回要跳转页面的路由即可。

Flutter集成iOS原生遇到的问题汇总:

下面列举一些最近在进行混编时遇到的一些问题:

Failed to register observatory port with mDNS with error -65555.

官方描述

On iOS 14 and higher, enable the Dart multicast DNS service in the Debug version of your app to add debugging functionalities such as hot-reload and DevTools via flutter attach.

解决方法

  • 将应用程序的Info.plist重命名为Info-Debug.plist。复制一个名为Info-Release.plist的副本,并将其添加到Xcode项目中

截屏2022-05-14 18.54.49.png

  • 在Info-Debug.plist中,添加键 Bonjour services 并将值设置为 _dartobservatory._tcp

可选的设置Privacy - Local Network Usage Description,并将值设置为Allow Flutter tools on your computer to connect and debug your application.This prompt will not appear on release builds.

截屏2022-05-14 18.58.50.png

  • 在TARGETS中, build settings 修改 Info.plist File 路径 path/to/Info.plist 为 path/to/Info-$(CONFIGURATION).plist.

截屏2022-05-14 19.02.49.png

In iOS 14+,debug mode Flutter apps can only be launched from Flutter tooling,IDEs with Flutter pl...

截屏2022-05-14 19.05.12.png

分析原因

在 iOS14 的真机上安装了 debug模式 编译出来的 flutter 应用,那么在断开编译安装连接后,将无法从桌面上打开该应用程序

解决方案

  1. 使用flutter的release模式,终端输入
flutter run --release
复制代码
  1. Modificar la configuración de main.dart

截屏2022-05-14 19.15.04.png

截屏2022-05-14 19.10.22.png

Motivo: probado: '/usr/lib/swift/App.framework/App' (no existe tal archivo), '/usr/lib/swift/App.framework/App' (no existe tal archivo),

Analiza las razones

Flutterno es App.frameworkimportado

Solución

Abra  Pods-xx-frameworks.shy agregue el siguiente código

install_framework "${PODS_ROOT}/../flutter/.ios/Flutter/App.framework"

No se encontró podspec para Flutteren../flutter/.ios/Flutter/engine

Analiza las razones

Falta este archivo en esta ruta

Solución

Puedes ver si este archivo se copia directamente en otros proyectos de Flutter.Este es el archivo relacionado con el motor de Flutter. Si hay una carpeta ios, vea si hay ese archivo debajo de este archivo

Símbolo indefinido: OBJC_CLASS $_TestViewController

截屏2022-05-14 19.42.06.png

Analiza las razones

Esta es una clase que creé que hereda de FlutterViewController y no la encontré

Solución

Agregue el archivo .m para esta clase en este

截屏2022-05-14 19.43.12.png

El widget inferior no sigue el teclado y rebota

Analiza las razones

El valor predeterminado resizeToAvoidBottomInset: true, dentro de Scaffold mediaQuery.viewInsets.bottom participará en el cálculo del tamaño de BoxConstraints, es decir, ajustará la posición inferior interna para coincidir con el teclado cuando este rebote.

Solución

configurarresizeToAvoidBottomInset: false

Seguiré actualizando si encuentro nuevos problemas en el futuro~

Resumir

Dado que el método de comunicación nativo se usaba en el pasado, era realmente problemático y la forma de usar este complemento es relativamente simple. Pero esto hace que la lectura del código sea un poco más difícil, no es tan legible como la comunicación nativa directa, todo tiene dos caras y depende de ti medirlo.

Supongo que te gusta

Origin juejin.im/post/7098506948026302478
Recomendado
Clasificación