本指南說明如何手動將另一個 由 Flutter 渲染的 iOS App Clip target 新增到你現有的 Flutter 專案或 add-to-app 專案中。

如需運作中的範例,請參考 GitHub 上的 App Clip 範例

步驟 1 - 開啟專案

#

開啟你的 iOS Xcode 專案,例如 ios/Runner.xcworkspace(完整 Flutter 應用程式)。

步驟 2 - 新增 App Clip target

#

2.1

在 Project Navigator 點選你的專案,以顯示專案設定。

在 target 列表底部按下 + 來新增一個新的 target。

2.2

為你的新 target 選擇 App Clip 類型。

2.3

在對話框中輸入你的新 target 詳細資訊。

Interface 請選擇 Storyboard

Language 請選擇與你原本 target 相同的語言。

(換句話說,為了簡化設定, 不要為 Objective-C 主 target 建立 Swift App Clip target,反之亦然。)

2.4

在接下來的對話框中, 啟用新 target 的新 scheme。

2.5

回到專案設定,打開 Build Phases 分頁。 將 Embedded App Clips 拖曳到 Thin Binary 之上。

步驟 3 - 移除不需要的檔案

#

3.1

在 Project Navigator 中,於新建立的 App Clip 群組內, 刪除除 Info.plist<app clip target>.entitlements 以外的所有檔案。

將檔案移至垃圾桶。

3.2

如果你沒有使用 SceneDelegate.swift 檔案, 請在 Info.plist 中移除對它的參考。

打開 App Clip 群組中的 Info.plist 檔案。 刪除 Application Scene Manifest 的整個 dictionary 項目。

步驟 4 - 共用建置組態

#

這一步對 add-to-app 專案來說不是必須的, 因為 add-to-app 專案會有自訂的建置組態和版本。

4.1

回到專案設定, 這次選擇專案本身而非任何 target。

Info 分頁下的 Configurations 展開群組,展開 DebugProfileRelease 項目。

對每一個項目,從下拉選單中為 App Clip target 選擇與主 App target 相同的值。

這樣你的 App Clip target 就能存取 Flutter 所需的建置設定。

iOS Deployment Target 設定為至少 16.0, 以利用 15MB 的大小限制。

4.2

在 App Clip 群組的 Info.plist 檔案中,設定:

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

步驟 5 - 共用程式碼與資源

#

選項 1 - 共用所有內容

#

假設你希望在標準 App 和 App Clip 中顯示相同的 Flutter UI, 可以共用相同的程式碼與資源。

對於以下每一個檔案:Main.storyboardAssets.xcassetsLaunchScreen.storyboardGeneratedPluginRegistrant.m 以及 AppDelegate.swift(若使用 Objective-C 則包含 Supporting Files/main.m), 選取檔案後,在檢查器的第一個分頁中, 於 Target Membership 勾選群組中也勾選 App Clip target。

選項 2 - 為 App Clip 客製化 Flutter 啟動

#

若採用此方式, 請不要刪除 步驟 3 中列出的所有檔案。 而是利用這些 scaffold 檔案及 iOS add-to-app API 來自訂啟動 Flutter。 例如顯示 自訂 Flutter 路由

步驟 6 - 新增 App Clip 關聯網域

#

這是 App Clip 開發的標準步驟。 請參考 Apple 官方文件

6.1

打開 <app clip target>.entitlements 檔案。 新增一個 Associated Domains 陣列型態。 在陣列中新增一列,內容為 appclips:<your bundle id>

6.2

同樣的關聯網域權限也需要加入到你的主 App。

將 App Clip 群組中的 <app clip target>.entitlements 檔案 複製到主 App 群組並重新命名為 與主 target 相同的名稱, 例如 Runner.entitlements

打開該檔案並刪除 Parent Application Identifiers 這一行(僅針對主 App 的權限檔案,App Clip 的權限檔案則保留)。

6.3

回到專案設定,選擇主 App 的 target, 打開 Build Settings 分頁。 將 Code Signing Entitlements 設定為 剛才為主 App 建立的第二個權限檔案的相對路徑。

步驟 7 - 整合 Flutter

#

這些步驟對 add-to-app 專案來說不是必須的。

7.1

對於 Swift target, 將 Objective-C Bridging Header 建置設定設為 Runner/Runner-Bridging-Header.h

換句話說, 與主 App target 的建置設定相同。

7.2

現在打開 Build Phases 分頁。按下 + 號 並選擇 New Run Script Phase

將這個新階段拖曳到 Dependencies 階段之下。

展開這個新階段,並在腳本內容中加入以下這一行:

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

取消勾選 Based on dependency analysis(根據相依性分析)。

換句話說, 這與主應用程式目標(main app target)的建置階段(build phases)設定相同。

這可確保在執行 App Clip 目標時, 你的 Flutter Dart 程式碼會被編譯。

7.3

點擊 + 號,然後再次選擇 New Run Script Phase(新增執行腳本階段)。 請將其保留為最後一個階段。

這次,請加入:

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

取消勾選 Based on dependency analysis(依據相依性分析)。

換句話說, 這與主應用程式 target 的 build phases 相同。

這樣可以確保你的 Flutter 應用程式及引擎 被嵌入到 App Clip bundle 中。

步驟 8 - 整合插件

#

8.1

開啟你的 Flutter 專案 或 add-to-app host 專案的 Podfile

對於全 Flutter 應用程式,請取代以下區段:

ruby
target 'Runner' do
  use_frameworks!
  use_modular_headers!

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

with:

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, '13.0',並將 version 設定為兩個目標的 iOS Deployment Target 中較低的那一個。

若為 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

請在命令列(Command Line Interface)中, 進入你的 Flutter 專案目錄, 然後安裝 pod:

cd ios
pod install

執行

#

你現在可以在 Xcode 中執行你的 App Clip target, 只需從方案下拉選單中選擇你的 App Clip target, 選擇一台 iOS 16 或更高版本的裝置,然後按下執行。

若要從頭開始測試啟動 App Clip, 也請參考 Apple 的測試你的 App Clip 啟動體驗文件。

除錯與熱重載

#

很遺憾,flutter attach 無法自動發現 App Clip 中的 Flutter 工作階段, 這是因為網路權限的限制。

因此,你必須將其複製並貼回 flutter attach 指令來進行連線。

例如:

flutter attach --debug-uri <copied URI>