从 App Store 下载或更新头条(6.9.2 或以上版本),找到 懂车帝 -> 热门车型,点击打开后即可体验 Flutter 的页面效果。

flutter 在 windows 上 ios真机调试 flutter开发ios教程_flutter


由于前期业务改造顺利,线上 Crash 少,性能良好,目前我们正在进行小视频模块的 Flutter 重构,即将上线。

本文主要介绍头条 iOS 端在接入 Flutter 的过程中,选择的技术方案,遇到的问题和未来的计划。虽然是以 iOS 为例,但很多内容都是双端通用的。

iOS 工程接入 Flutter 的已有方案

目前主流的方案中主要有两种,一种在 Google 的官方文档里 ,它最大的问题在于, 需要创建一步 BUILD PHASE 调用 shell 脚本去编译 Flutter。编译 Flutter 的过程需要本机有 Flutter 环境才行。

这显然是不能接受的。其实我们先不考虑 Flutter 这件事,不管是搭建什么类型的混合工程,都一定要保证以下两点:

  • 对原生工程无侵入:原生工程可以增加组件的依赖,但不能修改主工程的配置,更不能让原生工程对环境产生新的依赖。
  • 方便调试:不管是原生工程开发,调试新接入的模块(比如 Flutter),还是模块开发调试原生工程,都应该支持断点调试。
    很明显,官网的方案不满足第一点要求,我们不能让每个参与原生工程开发的同学,本机都安装 Flutter 环境。

从 Flutter 的官网教程 中可以看到,它支持 flutter run 命令或者从 IDE 启动 iOS 工程。其实只要观察一下 ios 目录下的 Runner.xcworkspace 工程就会发现,Flutter 项目运行的就是这个工程。当然如果直接把我们的 iOS 工程拷贝过来是无法运行的。至少在目前最新的 dev 分支(Tag:v0.10.0)上是不行的,因为 flutter 的代码中写死了工程的名字就是 Runner。

这也就催生了目前主流的,也是闲鱼最先介绍的方案,魔改 Flutter 源码,让它能运行自己的工程。然而个人觉得这种方式还是太 trick,主要有两个问题:

  • 后续如果 Flutter 升级了,还得把修改的部分应用到新的分支上去,并且修复冲突。
  • 如果公司或者业内有别的团队要用,接入成本比较高。
头条的混合工程方案

观察一下 Runner 的工程结构:

flutter 在 windows 上 ios真机调试 flutter开发ios教程_iOS_02


再看一眼 Flutter 编译脚本就会发现,这一步并不是必须放在主工程的 BUILD 阶段进行。只要拥有 Flutter 的编译产物,项目就可以接入 Flutter 的功能了。因此头条选择的方案是:

  • 利用 flutter build ios 和 flutter build ios --debug 命令,先后构建两种模式下的产物并上传到 CDN
  • 构建一个 Pod,并且让 Pod 依赖上述产物

在第一步中,运行 flutter build ios 实际上会依赖 Runner 工程,相当于是我们借助这个空壳去得到产物。不过要想编译通过,还需要做如下两个微小的改动:

  • 修改项目的 Bundle ID,使用自己的证书。否则无法通过签名
  • 打开 Xcode -> File -> Workspace -> Setting,把 BUILD_SYSTEM 切换为 Legacy,否则会产生编译错误

第二步中,重点在于如何让 Pod 动态的下载资源,因为需要指定使用哪个版本,哪种模式的 Flutter 产物。我们目前的策略是在打包机器上使用 Release 模式产物,在开发机器上使用 Debug 模式产物。

至于动态指定版本号,可以这样写:

s.prepare_command = "bash ./BDFlutterDownload.sh"
s.vendored_frameworks = 'Framework/*.framework'
s.resources = 'Framework/flutter_assets'

通过 prepare_command 语法,可以在 Pod Install 的过程中执行 shell 脚本,把产物下载到 Framework 文件夹中,只要把版本号写到脚本中,并且及时更新就可以了。

调试 Flutter

上述方案解决了 Flutter 工程接入的问题,因为是编译后的资源接入,我们还需要保证 Flutter 开发的同学可以正常调试。这里以最新的 dev 分支举例(Tag:v0.10.0)。

如果是 Flutter 开发的同学,不关心 iOS 开发的细节,可以找到打包后的 app 文件,然后使用 flutter run --use-application-binary 指定被调试应用的路径:

flutter 在 windows 上 ios真机调试 flutter开发ios教程_flutter_03