用|用 Flutter 打包 iOS 应用的一些细节知识

用|用 Flutter 打包 iOS 应用的一些细节知识
文章图片
本文将向大家介绍 Flutter 的构建系统是如何将 Flutter 项目 (及其资源) 转换为 iOS 应用包的。我希望揭开一些构建步骤的神秘面纱,并解释生成出来的工件的用途,方便大家将这个流程集成到自己的构建环境中。关于工作流程,请注意: 在构建要发布的应用时,您可以直接使用 Flutter 工具,这样会简化构建流程。但也有一部分开发者可能会发现这个流程的可配置性不太理想,或是不适用于他们的构建设置或持续集成 (CI) 设置。如果您使用自定义的 Xcode 或 Gradle 设置,那 Flutter 工具带来的所有开箱即用的便利都是可选的,您完全可以尽情调整,以让它适合自己的工作流程。本文中的所有信息均适用于准备发布到 App Store 的 iOS 应用包。也就是说,项目是根据 Flutter 的发布模式 (Release Mode) 构建的。编译为 Debug 或 Profile 模式会使用不同的运行时和打包模型,以便支持热重装和观测工具。

  • 热重载
    https://flutter.io/hot-reload/
  • 观测工具
    https://dart-lang.github.io/observatory/get-started.html


Flutter 应用会将所有的用户界面在原生视图层级结构中渲染为单一的视图,如下图: 用|用 Flutter 打包 iOS 应用的一些细节知识
文章图片
△ 在 Xcode 中看到的 Flutter 应用视图层级结构
应用包 使用 flutter build ios --release 命令创建 (或使用 IDE 直接创建) 的应用包 (application bundle) 看起来和典型的 iOS 应用包是相似的,该代码包内含应用可执行文件,以及所有引用到的框架和资源。
比如 Flutter 为 Runner 这个应用生成的代码包结构如下:
用|用 Flutter 打包 iOS 应用的一些细节知识
文章图片
编译应用 您在编译应用的发布版本 (Release 版本,注意和 Profile 和 Debug 不同) 时,需要来自buildbots 和主机的工件。(说到 buildbots,引擎部分使用的是 GN 和 Ninja,这里就不展开细说了,如果想要贡献代码至 Flutter,请查看我们的官方指引文档。)
  • 了解 Flutter 的构建模式
    https://github.com/flutter/flutter/wiki/Flutter's-modes
  • 了解 buildbots
    https://build.chromium.org/p/client.flutter/waterfall
  • 贡献代码至 Flutter
    https://github.com/flutter/engine/blob/master/CONTRIBUTING.md
安装 SDK 时,Flutter 工具会缓存在您的电脑上。您可以在 bin/cache 目录里查看它们。如果您决定将构建过程的任何步骤集成到自己的构建系统中,这个目录里包含了使用 Flutter 所需的所有工具。我们接下来花几节文字来说明一下 Flutter iOS 应用包中特有的一些文件。
Flutter Engine 框架包 Flutter.framework 目录被打包为 iOS framework bundle,其中包括:
  • Flutter 引擎: 内含核心库 (如图形、文件和网络 I/O、可访问性支持、插件体系架构)、DartVM 和 Skia 渲染器。
  • Flutter 引擎引用的资源: 目前仅含 ICU 数据。
Flutter 引擎的 framework bundle 由 buildbots 生成,然后 Flutter 工具将其下载并缓存在电脑本地。
  • Flutter 引擎
    https://github.com/flutter/engine
AOT 框架包 App.framework 包内含所有由用户编写的 Dart 应用代码的 AOT (Ahead-Of-Time) 快照,以及为 Flutter 框架和插件编写的 Dart 代码,代码格式为 armv7s 和 aarch64。
在编译发布版本时,编译器会对 Dart 代码进行筛选,只有实际使用到的代码才会被打包。您的电脑上缓存的 gen_snapshot 工具会生成创建 App.framework 代码包所需的工件。AOT 快照前面提到的 AOT 快照库里包含从 Dart 编译出来的 AOT 原生机器码。由 gen_snapshot 生成的快照库包含了四个主要标识。这些标识可以通过 nm 命令拿掉。例如:
$ nm -gU Runner.app/Frameworks/App.framework/App

上述 4 个标识的具体说明如下:
  • Dart VM 快照 (kDartVmSnapshotData): 代表 isolate 之间共享的 Dart 堆 (heap) 的初始状态。有助于更快地启动 Dart isolate,但不包含任何 isolate 专属的信息。
  • Dart VM 指令 (kDartVmSnapshotInstructions): 包含 VM 中所有 Dart isolate 之间共享的通用例程的 AOT 指令。这种快照的体积通常非常小,并且大多会包含程序桩 (stub)。
  • Isolate 快照 (kDartIsolateSnapshotData): 代表 Dart 堆的初始状态,并包含 isolate 专属的信息。
  • Isolate 指令 (kDartIsolateSnapshotInstructions): 包含由 Dart isolate 执行的 AOT 代码。
调用 gen_snapshot 很简单。只需将其指向 Dart 源代码,它就会为这四个标识中的每一个提供 Blob。然后,Xcode 将这些打包到 iOS framework bundle 中,这个过程和使用 C、C++、Objective-C 或 Swift 编写的框架一样。
  • 进一步了解如何配置快照和引擎https://github.com/flutter/engine/wiki/Flutter-Engine-Operation-in-AOT-Mode#snapshot-generation
除了打包代码之外,Flutter 工具还会读取项目 pubspec.yaml 文件中所列出的资源,从而确保应用 (及其使用的插件) 所引用的资源也会被收录进应用包中。
总结 另外,如果你想一起进阶,不妨添加一下交流群1012951431,选择加入一起交流,一起学习。期待你的加入!(进群可领取学习礼包)
构建 iOS app bundle 的关键点如下:
  • 您可以将 Flutter 视图放置在本地视图层级结构中的任何位置。Flutter 渲染出来的所有内容都会合并到此视图中。
  • Dart 代码像其他任何 C++ / Objective-C / Swift 代码库一样,都会被编译为原生机器码,并打包为库或 framework bundle。这意味着所有崩溃报告和标识工具都会以相同的方式作用于 Dart AOT 代码。
  • 您可以将 Flutter 集成到自己的构建系统中,而不必依赖开发设备上的 Flutter 工具 (尽管使用这些工具可以让您的工作更轻松些)。所有工具都可以在 Flutter SDK 的 bin/cache 目录中找到。
【用|用 Flutter 打包 iOS 应用的一些细节知识】转载地址: https://mp.weixin.qq.com/s/PsvVFoB91_jGzibFPIwnIw

    推荐阅读