iOS项目(Swift),使用Flutter进行混合开发
一、创建flutter_module
先创建flutter module
项目,参考官方文档,先cd
至目标文件夹,执行命令为
flutter create --template module flutter_module
创建成功后,打开flutter_module
项目,打开pubspec.yaml
文件,添加所需的依赖
执行命令,更新依赖。
执行 flutter run
命令,生成pod
创建Swift
项目,打开Swift
项目中的 Podfile
添加相关pod命令
执行pod install
命令(每次 flutter_module
中的 pubspec.yaml
更改后,都需要再次执行 pod install
命令)
我们在应用启动时的 App Delegate 中创建了一个 FlutterEngine
并作为属性暴露给外界。
在 SceneDelegate.swift 中
或 在 AppDelegate.swift
:
在view controller中使用
二、Flutter与原生通信
Flutter 与原生之间的通信依赖灵活的消息传递方式
-
应用的Flutter部分通过平台通道(platform channel)将消息发送到其应用程序的所在的宿主(iOS或Android)应用(原生应用)
-
宿主监听平台通道,并接收该消息。然后它会调用该平台的 API,并将响应发送回客户端,即应用程序的 Flutter 部分
Flutter 与原生存在三种交互方式
-
MethodChannel:用于传递方法调用(method invocation)通常用来调用 native 中某个方法
-
BasicMessageChannel:用于传递字符串和半结构化的信息,这个用的比较少
-
EventChannel:用于数据流(event streams)的通信。有监听功能,比如电量变化之后直接推送数据给flutter端
三种 Channel 之间互相独立,各有用途,但它们在设计上却非常相近。每种 Channel 均有三个重要成员变量:
-
name: String类型,代表 Channel 的名字,也是其唯一标识符
-
messager:BinaryMessenger 类型,代表消息信使,是消息的发送与接收的工具
-
codec: MessageCodec 类型或 MethodCodec 类型,代表消息的编解码器
Flutter端代码:
进入flutter页面,接收到原生数据:
点击发送数据到原生按钮,原生返回数据如下:
2、BasicMessageChannel的使用
它是可以双端通信的,Flutter 端可以给 iOS 发送消息,iOS 也可以给 Flutter 发送消息。
iOS端代码:
Flutter端代码:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class BasicMessageChannelDemo extends StatefulWidget { const BasicMessageChannelDemo({Key? key}) : super(key: key); @override _BasicMessageChannelDemoState createState() => _BasicMessageChannelDemoState(); } class _BasicMessageChannelDemoState extends State<BasicMessageChannelDemo> { //Flutter 端创建 MethodChannel 通道,用于与原生端通信: var channel = const BasicMessageChannel( 'com.flutter.guide.BasicMessageChannel', StandardMessageCodec()); var _data; var _nativeData; @override void initState() { // TODO: implement initState super.initState(); //监听并接收原生数据 channel.setMessageHandler((message) async { setState(() { _nativeData = message; }); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('BasicMessageChannel'), centerTitle: true, ), body: Column( children: [ const SizedBox( height: 50, ), ElevatedButton( onPressed: () async { //向原生发送数据 var result = await channel.send({'name': 'laowang', 'age': 25}); // var name = result['name']; // var age = result['age']; setState(() { _data = '$result'; }); }, child: const Text('发送数据到原生'), ), Text('原生返回数据:$_data'), Text('接收到原生发送的数据:$_nativeData'), ], ), ); } }
3、EventChannel的使用
只能是原生发送消息给 Flutter 端,例如监听手机电量变化,网络变化,传感器等。
iOS端代码:
Flutter端代码:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class EventChannelDemo extends StatefulWidget { const EventChannelDemo({Key? key}) : super(key: key); @override _EventChannelDemoState createState() => _EventChannelDemoState(); } class _EventChannelDemoState extends State<EventChannelDemo> { //Flutter 端创建 EventChannel 通道,用于与原生端通信: //com.flutter.guide.EventChannel 是 EventChannel 的名称,原生端要与之对应。 final _eventChannel = const EventChannel('com.flutter.guide.EventChannel'); var _data; @override void initState() { // TODO: implement initState super.initState(); //监听原生端发送的消息: _eventChannel.receiveBroadcastStream().listen(_onData); } _onData(event) { setState(() { _data = event; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("EventChannelDemo"), centerTitle: true, ), body: Center( child: Text('$_data'), ), ); } }
使用链接:https://flutter.cn/docs/development/add-to-app/ios/add-flutter-screen?tab=vc-uikit-swift-tab