添加 iOS App Clip target

这个指南介绍了如何手动添加另一个使用 Flutter 来渲染的 iOS App Clip target, 并将它集成到你现有的 Flutter 项目或 add-to-app 项目。

要查看完整可用的示例,请参阅 GitHub 上的 App Clip 示例

步骤 1 - 打开项目

#

打开你的 iOS Xcode 工程,例如你的纯 Flutter 项目中的 ios/Runner.xcworkspace

步骤 2 - 添加一个 App Clip 的 target

#

2.1

点击你项目的 Project Navigator 来显示工程设置。

点击 target 列表底部的 + 来添加一个新的 target。

2.2

为你的新 target 选择 App Clip 类型。

2.3

在对话框为你的新 target 输入详情。

选择与你原来的 target 相同的 编程语言

(换句话说,请勿为 Objective-C target 创建 Swift 类型的 App Clip target,反之亦然,以简化设置。)

2.4

在接下来的对话框中,为新的 target 激活 (activate) 一个新的 scheme。

2.5

返回项目设置,打开 Build Phases 选项卡。将 Embedded App Clips 拖动至 Thin Binary 上方。

步骤 3 - 移除不需要的文件

#

3.1

在项目 Project Navigator 的新创建的 App Clip 组中,将除了 Info.plistApp Clip target.entitlements 以外的所有内容删除。

移动文件到废纸篓。

3.2

如果你不使用 SceneDelegate.swift 文件,移除在 Info.plist 中对应的引用。

打开 App Clip 组中的 Info.plist。删除 Application Scene Manifest 字典条目。

步骤 4 - 共享构建配置

#

对于 add-to-app 项目,此步骤不是必需的,因为 add-to-app 有自己的自定义构建配置和版本。

4.1

返回项目设置,现在选择 Project 条目,而不是 Targets 里的任何 target。

Info 选项卡页中的 Configurations 可扩展组下,展开 DebugProfileRelease 条目。

每一个 App Clip target 的下拉菜单的值都应该与常规应用 target 中的值相同。

这使你的 App Clip target 可以访问 Flutter 所需的构建设置。

iOS Deployment Target 至少设置为 16.0,这样设置后的大小限制将会提高至 15MB。

4.2

在 App Clip 组的 Info.plist 文件中,设置:

  • Build version string (short) to $(FLUTTER_BUILD_NAME)
  • Bundle version to $(FLUTTER_BUILD_NUMBER)

步骤 5 - 共享代码和资源

#

选项 1 - 共享所有东西

#

假设你的目标是在 App Clip 中显示与普通应用相同的 Flutter UI,并共享相同的代码和资源。

对于以下每一个文件: Main.storyboardAssets.xcassetsLaunchScreen.storyboardGeneratedPluginRegistrant.mAppDelegate.swift,(如果你是 Objective-C 还应该包括 Supporting Files/main.m)选择文件并且在检查器中选择第一个选项卡,并且在 Target Membership 选中 App Clip

选项 2 - 为 App Clip 自定义 Flutter 的启动器

#

在这个例子中,不需要删除在 步骤 3 中的任何东西。相对的,使用 iOS add-to-app APIs 的模板来自定义 Flutter 启动器。可以参考示例 自定义 Flutter 路由

步骤 6 - 添加 App Clip 的关联域名

#

这是一个 App Clip 开发的标准步骤。请查看 苹果官方文档

6.1

打开 <app clip target>.entitlements 文件。添加 Associated Domains 数组。添加一行 appclips:<your bundle id> 到数组中。

6.2

同样的相关域名权利也需要添加到你的主应用程序中。

<app clip target>.entitlements 文件从 App Clip 组复制到主应用程序组,并将其重命名为与主目标相同的名称,例如 Runner.entitlements

打开文件并删除主应用程序授权文件的 Parent Application Identifiers 条目(将该条目保留为 App Clip 的授权文件)。

6.3

返回项目设置,选择主应用 target,打开 Build Settings 选项卡。设置 Code Signing Entitlements 的值为主应用创建的第二个授权文件的相对路径。

步骤 7 - 整合 Flutter

#

add-to-app 不需要这些步骤。

7.1

如果是 Swift target,设置 Objective-C Bridging Header 构建配置为 Runner/Runner-Bridging-Header.h

换句话说,与主应用程序 target 的构建设置相同。

7.2

现在打开 Build Phases 选项卡。点击 + 并且选择 New Run Script Phase

拖动新的 phase 到 Dependencies phase。

展开新 phase 并将以下内容添加到脚本:

bash
/bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build

取消选中 Based on dependency analysis

简单来说,与主应用程序 target 的构建设置相同。

This ensures that your Flutter Dart code is compiled when running the App Clip target.

7.3

再次点击 + 并且选择 New Run Script Phase。这是最后一个 phase。

这次添加如下内容:

bash
/bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed_and_thin

Uncheck Based on dependency analysis.

简单来说,与主应用程序 target 的构建设置相同。

这将确保你的 Flutter 应用程序和引擎嵌入到 App Clip bundle 中。

Step 8 - 整合插件

#

8.1

在你的 Flutter 项目或是 add-to-app 的宿主项目中打开 Podfile 文件。

如果是完整的 Flutter 项目,替换下面这段代码:

ruby
target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

为:

ruby
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))

target 'Runner'
target '<name of your App Clip target>'

在文件的开始,需要把 platform :ios, '12.0' 的注释(开头的 #)删除,并且为你的 2 个 target 设置最低可运行的 iOS 系统版本。

如果是 add-to-app,紧跟下面的代码:

ruby
target 'MyApp' do
  install_all_flutter_pods(flutter_application_path)
end

添加:

ruby
target 'MyApp' do
  install_all_flutter_pods(flutter_application_path)
end

target '<name of your App Clip target>'
  install_all_flutter_pods(flutter_application_path)
end

8.2

在命令行中,目前工作目录需要是你的 Flutter 项目目录,然后安装 pod:

cd ios
pod install

运行

#

你现在可以在 Xcode 的 scheme 下拉中选择并运行你的 App Clip target 了,选择一个 iOS 16 或更高版本的设备并点击运行。

要从头测试 App Clip 的启动,你也可以查看苹果公司的文档 测试你的 App Clip 的启动体验

调试和热重载

#

不幸的是,由于网络权限的原因,flutter attach 无法在 App clip 中自动发现 Flutter 会话。

为了调试 App clip 并使用诸如热重新加载之类的功能,必须在运行应用后从 Xcode 中的控制台输出中查找 Observatory URI。

你需要复制粘贴它们到 flutter attach 来连接。

例如:

flutter attach --debug-uri <copied URI>