新增 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 並將以下內容新增到指令碼:

/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。

這次新增如下內容:

/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 專案,替換下面這段程式碼:

target 'Runner' do
  use_frameworks!
  use_modular_headers!

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

為:

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,緊跟下面的程式碼:

target 'MyApp' do
  install_all_flutter_pods(flutter_application_path)
end

新增:

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>