深度連結(deep linking)允許應用程式使用者透過 URI 啟動應用程式。 這個 URI 包含 scheme、host 和 path, 並可直接開啟應用程式中的特定螢幕。

universal link(通用連結)是 iOS 裝置專屬的一種深層連結(deep link), 僅使用 httphttps 協定。

要設定 universal links,你必須擁有一個網域名稱。 作為暫時性的解決方案, 你可以考慮使用 Firebase HostingGitHub Pages

當你設定好深層連結(deep links)後,可以進行驗證。 如需進一步了解,請參閱驗證深層連結

建立或修改 Flutter 應用程式

#

撰寫一個能夠處理傳入 URL 的 Flutter 應用程式。

本範例使用 go_router 套件來處理路由。 Flutter 團隊維護 go_router 套件。 它提供了簡單的 API 來處理複雜的路由情境。

  1. 若要建立新應用程式,請輸入 flutter create <app-name>

    flutter create deeplink_cookbook
  2. 若要將 go_router 套件作為相依套件加入, 請執行 flutter pub add

    flutter pub add go_router
  3. 為了處理路由,請在main.dart檔案中建立一個GoRouter物件:

    main.dart
    dart
    import 'package:flutter/material.dart';
    import 'package:go_router/go_router.dart';
    
    void main() => runApp(MaterialApp.router(routerConfig: router));
    
    /// This handles '/' and '/details'.
    final router = GoRouter(
      routes: [
        GoRoute(
          path: '/',
          builder: (_, _) => Scaffold(
            appBar: AppBar(title: const Text('Home Screen')),
          ),
          routes: [
            GoRoute(
              path: 'details',
              builder: (_, _) => Scaffold(
                appBar: AppBar(title: const Text('Details Screen')),
              ),
            ),
          ],
        ),
      ],
    );

調整 iOS 建置設定

#
  1. 啟動 Xcode。

  2. 在 Flutter 專案的 ios 資料夾中,開啟 ios/Runner.xcworkspace 檔案。

新增關聯網域(Associated Domains)

#
  1. 如有需要,啟動 Xcode。

  2. 點擊最上層的 Runner

  3. 在編輯器中,點擊 Runner target。

  4. 點擊 Signing & Capabilities

  5. Signing & Capabilities 下方,點擊 + Capability 以新增功能。

  6. 點擊 Associated Domains

    Xcode associated domains screenshot
  7. Associated Domains 區塊中,點擊 +

  8. 輸入 applinks:<web domain="">。請將 <web domain=""> 替換為你自己的網域名稱。

    Xcode add associated domains screenshot

  1. 使用你偏好的編輯器開啟 ios/Runner/Runner.entitlements XML 檔案。

  2. <dict> 標籤內新增一個關聯網域(associated domain)。

    xml
    <!--?xml version="1.0" encoding="UTF-8"?-->
    
    <plist version="1.0">
    <dict>
      <key>com.apple.developer.associated-domains</key>
      <array>
        <string>applinks:example.com</string>
      </array>
    </dict>
    </plist>
  3. 儲存 ios/Runner/Runner.entitlements 檔案。

若要檢查你所建立的關聯網域是否可用,請依照下列步驟操作:

  1. 如有需要,啟動 Xcode。

  2. 點擊最上層的 Runner

  3. 在編輯器中,點擊 Runner target。

  4. 點擊 Signing & Capabilities。 這些網域應該會顯示在 Associated Domains 區段中。

    Xcode add associated domains screenshot

你已完成應用程式的深度連結(deep linking)設定。

將你的應用程式與網域關聯

#

你需要在網域上託管一個 apple-app-site-association 檔案。 這個檔案會告訴行動瀏覽器,應該開啟哪一個 iOS 應用程式,而不是瀏覽器本身。 要建立這個檔案,請找到你在前一節建立的 Flutter 應用程式的 appID

找到 appID 的組成部分

#

Apple 會將 appID 格式化為 <team id>.<bundle id>

例如: 假設 team ID 為 S8QB4VV633, bundle ID 為 com.example.deeplinkCookbook, 你應該輸入一個 appID 條目為 S8QB4VV633.com.example.deeplinkCookbook

建立並託管 apple-app-site-association JSON 檔案

#

這個檔案使用 JSON 格式。 儲存此檔案時,請勿包含 .json 檔案副檔名。 根據 Apple 的文件, 此檔案內容應類似如下:

json
{
  "applinks": {
    "apps": [],
    "details": [
      {
        "appIDs": [
          "S8QB4VV633.com.example.deeplinkCookbook"
        ],
        "paths": [
          "*"
        ],
        "components": [
          {
            "/": "/*"
          }
        ]
      }
    ]
  },
  "webcredentials": {
    "apps": [
      "S8QB4VV633.com.example.deeplinkCookbook"
    ]
  }
}
  1. appIDs 陣列中的一個值設為 <team id>.<bundle id>

  2. paths 陣列設為 ["*"]paths 陣列用來指定允許的 universal links(通用連結)。 使用星號時,* 會將所有路徑重新導向至 Flutter 應用程式。 如有需要,請將 paths 陣列的值調整為更適合您應用程式的設定。

  3. 將檔案主機設於類似以下結構的 URL 上。

    <webdomain>/.well-known/apple-app-site-association

  4. 確認您的瀏覽器可以存取此檔案。

測試 universal link(通用連結)

#

請使用實體 iOS 裝置或模擬器(Simulator)來測試 universal link。

  1. 在測試前, 請先將 Flutter 應用程式安裝到 iOS 裝置或模擬器上, 並在目標裝置上使用 flutter run

    Simulator screenshot

    完成後, Flutter 應用程式會顯示在 iOS 裝置或模擬器的主畫面上。

  2. 若您使用模擬器進行測試,請使用 Xcode CLI:

    xcrun simctl openurl booted https://<web domain>/details
  3. 如果你在實體 iOS 裝置上進行測試:

    1. 開啟 備忘錄(Note)App。
    2. 備忘錄 App 中輸入該 URL。
    3. 點擊產生的連結。

    如果成功,Flutter 應用程式會啟動並顯示其詳細資訊螢幕。

    Deeplinked Simulator screenshot

尋找原始碼

#

你可以在 GitHub 儲存庫中找到 deeplink_cookbook 範例的原始碼。