需求
将 Flutter App 模块独立出来,内嵌到 iOS 原生中使用,这里使用的是 framework 方式,优点是多人/多公司/部门开发时,不需要其他人安装 Flutter 环境,只需要引入 iOS Framework 库集成即可。
步骤
依据文档,Flutter 打包 Framework 需为 Flutter Module 类型。
-
执行命令
flutter create -t module flutter_module创建FlutterModule工程 -
执行命令
flutter build ios-framework --output=some/path/MyApp/Flutter/生成frameworks生成的文件结构为:
some/path/MyApp/ └── Flutter/ ├── Debug/ │ ├── Flutter.xcframework │ ├── App.xcframework │ ├── FlutterPluginRegistrant.xcframework (only if you have plugins with iOS code) │ └── example_plugin.xcframework (each plugin is a separate framework) ├── Profile/ │ ├── Flutter.xcframework │ ├── App.xcframework │ ├── FlutterPluginRegistrant.xcframework │ └── example_plugin.xcframework └── Release/ ├── Flutter.xcframework ├── App.xcframework ├── FlutterPluginRegistrant.xcframework └── example_plugin.xcframeworkFlutter.xcframework:Flutter引擎
App.xcframework:APP代码逻辑
需要注意,如果工程中含有原生端代码插件,则会生成
FlutterPluginRegistrant.xcframework和xxx_plugin.xcframework,否则则没有。 -
在原生iOS端集成
按照文档初始化Flutter引擎及嵌入Flutter页面(在 iOS 应用中添加 Flutter 页面),需要注意静态库需要将选项设为
Do Not Embed
技巧
-
如何在已有Flutter APP类型项目中快速打包framework
一般来说,如果是将已有 Flutter APP 打包为 Framework 的需求,创建拷一份代码给 Flutter Module 类型的话,比较不太好维护。而且 Flutter Module 的文件结构性质(.ios),使项目每次 flutter clean 的时候都会删掉并在 flutter pub get 的时候重新生成,导致我们有些特定配置丢失。
尝试在Flutter APP类型工程里执行
flutter build ios-framework命令,确实也是可以生成frameworks,但是发现当项目中含有插件的时,则会丢失插件的framework。通过比对APP与Module类型的结构,发现APP对比Module有些文件不一致。于是手动在APP工程的ios/Flutter 文件夹下增加 FlutterPluginRegistrant同时,在项目的Podfile文件中增加
pod 'FlutterPluginRegistrant', :path => File.join('Flutter', 'FlutterPluginRegistrant'), :inhibit_warnings => true之后执行
flutter build ios-framework命令打包集成测试正常。 -
原生启动Flutter引擎时如何便捷传值给Flutter层
参见上篇文章 《Flutter混编之iOS原生传值给Flutter》
-
打包脚本备忘
#!/bin/sh project_path=$(pwd) project_last_path=${project_path%/*} echo "" echo "=============== 构建开始 ===============" clean_tips="执行flutter clean(默认:n) [ y/n ]" echo $clean_tips read -t 5 is_clean if [ ! -n "${is_clean}" ];then is_clean="n" fi while([[ $is_clean != "y" ]] && [[ $is_clean != "n" ]]) do echo "错误!只能输入[ y/n ] !!!" echo $clean_tips read is_clean done echo "请输入选择模式(默认:0) [ release: 0 , all: 1 ] " read -t 5 number if [ ! -n "${number}" ];then number=0 fi while([[ $number != 0 ]] && [[ $number != 1 ]]) do echo "错误!只能输入0或者1!!!" echo "请输入选择模式? [ release: 0 , all: 1 ] " read number done echo "=============== 复制Podfile配置 ===============" cp -fr "$project_path/Podfile" "$project_last_path/Podfile" if [ ${is_clean} = "y" ];then echo "=============== 开始清理 ===============" flutter clean fi echo "=============== 构建FLUTTER_IOS_FRAMEWORK ===============" if [ $number == 0 ];then flutter build ios-framework --release --no-debug --no-profile else flutter build ios-framework fi # TODO 提供选项将新产物复制到旧SDK目录里 仅复制APP/全部复制 echo "=============== 复制产物 ===============" echo "=============== 构建完成 ===============" echo "" exit 0