Flutter 混合工程体系 一文中,阐述了Flutter 三种开发模式,在实际业务中搭建持续集成时,我们更希望本地开发使用混合模式,持续集成使用解耦模式, 主要是解决以下两个问题:

  1. 混合模式:开发调试方便,包括热更新, Native 与 Flutter 开发源码断点调试
  2. 解耦模式:不侵入 iOS Native工程,不对 Flutter 环境产生依赖,可以单独独立构建打包

我们这里重点阐述 解耦模式,要对 iOS 与 Flutter 进行解藕,就需要分析混合模式最终生成的 iPA文件内容长啥样和 Flutter 构建脚本。

iOS Flutter 项目 IPA 文件结构分析

ipa 文件 改成 zip 文件,然后解压,进入 Payload 文件夹,会看到一个 .app 的文件,右键显示包内容,即可看到类型如下内容(该测试项目是用 swfit + flutter )。
经过分析,与普通的iOS 项目相比,就多了个 Flutter.framework 文件。经过查阅资料,

image.png

构建 iOS Flutter Framework 和 插件

  • flutter build ios 编译 App.framework, 模拟器需要使用 —simulator —no-codesign 标识
  • 复制 App.framework 和 Flutter.framework 到临时目录
  • 复制 Flutter 生成的 iOS 桥接 FlutterPluginRegistrant 插件到临时目录
  • 处理 Flutter 项目的依赖插件,复制 .a 文件和 .h 头文件到临时目录

util.zip

  1. #!/bin/bash
  2. root=`pwd`
  3. . "${root}/script/util.sh"
  4. target_dir=../HappyIOS/Flutter
  5. flutter_engine_dir=ios
  6. build_app_dir=${root}/build/ios/iphonesimulator
  7. build_lib_dir=${root}/build/ios/Debug-iphonesimulator
  8. build_cmd="flutter build ios --simulator --no-codesign --debug"
  9. if [[ $build = "release" ]]
  10. then
  11. flutter_engine_dir=ios-release
  12. build_app_dir=${root}/build/ios/iphoneos
  13. build_lib_dir=${root}/build/ios/release-iphoneos
  14. build_cmd="flutter build ios --release"
  15. fi
  16. green "--flutter module build start--"
  17. yellow ">>${build_cmd}"
  18. flutter clean
  19. # flutter build ios --simulator --no-codesign --${build}
  20. ${build_cmd}
  21. green "--flutter module build end--"
  22. # copy Flutter.framework and App.framework
  23. green "--flutter build file copy start--"
  24. rm -rf ${target_dir}/**
  25. # copy flutter engine framework
  26. cp -r ${flutter_root}/bin/cache/artifacts/engine/${flutter_engine_dir}/Flutter.framework ${target_dir}
  27. # cp -rf ${build_app_dir}/Runner.app/Frameworks/Flutter.framework ${target_dir}
  28. cp -rf ${build_app_dir}/Runner.app/Frameworks/App.framework ${target_dir}
  29. cp -rf ${build_lib_dir}/FMDB "${target_dir}/FMDB"
  30. cp -rf ${build_lib_dir}/FlutterPluginRegistrant "${target_dir}/FlutterPluginRegistrant"
  31. cp -rf ${root}/.ios/Flutter/FlutterPluginRegistrant/Classes/GeneratedPluginRegistrant.h "${target_dir}/FlutterPluginRegistrant/"
  32. for line in $(cat .flutter-plugins)
  33. do
  34. arr=(${line/=/ })
  35. name=${arr[0]}
  36. path=${arr[1]}
  37. plugin_name=`basename $path`
  38. plugin_dir=$(dirname $path)
  39. plugin=${path}android
  40. a_header="${path}ios/Classes/*.h"
  41. a_file="${build_lib_dir}/${name}"
  42. if [ ! -f $arr ]
  43. then
  44. cp -rf ${a_file} ${target_dir}
  45. cp -rf ${a_header} ${target_dir}/${name}
  46. else
  47. echo "$aar is not exists"
  48. fi
  49. done
  50. green "--flutter build file copy end--"

iOS Native 本地引用构建产物文件

通过 Xcode 为 iOS Native 项目添加 Flutter 构建产物依赖. Xcode 点击项目名,找到 Build Phases Tab:

  • 在Link Binary Width Libraries 添加所有构建产物的依赖
  • 点击左上角加个添加一个 New Copy Files Phases 选项,然后添加 Flutter.framework 和 App.framework ,

image.png

iOS Native 通过 Pod 引用构建产物文件

根据Flutter构建的产物构建编写 Pod 插件,然后 让 iOS Native 工程通过 Pod 方式依赖