Flutterでディープリンクを修正する機会があったので、設定・実装の全体像をまとめてみました。

ディープリンクとは

WebサイトのURLから、直接アプリのコンテンツを開くことができる技術のことです。

iOSではUniversal Links(ユニバーサルリンク)と呼ばれ、Androidではアプリリンクと呼ばれています。
(技術的な仕様は少し違いますがここでは省きます)

X(旧Twitter)やInstagramなどのURLをタップしたときに、アプリをインストールしていれば、ブラウザではなくアプリでそのコンテンツが表示されるものです。

アプリ側の設定方法

iOS

まずはApple Developper Programのサイトの「Certificates, Identifiers & Profiles」のページを開き、「Associated Domains」をONにします。

次にXcodeの「Runner」→「Signing & Capabilities」→「Associated Domains」に後述するapple-app-site-associationを保存するドメインを指定します。

Android

android/app/src/main/AndroidManifest.xmlに以下を追加します。

<!-- App Links -->
<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <!-- Accepts URIs that begin with https://YOUR_HOST -->
    <data
      android:scheme="https"
      android:host="[YOUR_HOST]" />
</intent-filter>

apple-app-site-associationの設定方法

iOSではアプリとWebサイトを紐づけるために、apple-app-site-associationというファイルを用意し、サーバーにアップロードします。

実際のファイルは以下のように書きます。

{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "ABCDFE.com.example.app",
                "paths": ["*"]
            }
        ]
    }
}

「appID」はdevelopperチームのIDに、アプリのバンドルIDを繋げたものです。
また「paths」にはWebサイトのパスを指定できます。今回は全てのパスを渡せるワイルドカードを使っています。

そして以下の場所でファイルにアクセスできるようにアップロードします。

https://{domain}/.well-known/apple-app-site-association

assetlinks.jsonの設定方法

AndroidでもアプリとWebサイトを紐づけるために、assetlinks.jsonというファイルを用意し、サーバーにアップロードします。

記載内容は以下のとおりです。

 [{
    "relation": ["delegate_permission/common.handle_all_urls"],
    "target": {
      "namespace": "android_app",
      "package_name": "com.example",
      "sha256_cert_fingerprints":
      ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
    }
  }]

そして以下の場所でファイルにアクセスできるようにアップロードします。

https://{domain}/.well-known/assetlinks.json

実装方法

↓↓「Uni Links」というプラグインを使います。
https://pub.dev/packages/uni_links

まずはアプリが開始された時のUriオブジェクトを返す処理を行います。
この処理はアプリ開始の初期に一度だけ実行します。

import 'dart:async';
import 'package:uni_links/uni_links.dart';
import 'package:flutter/services.dart';

Future _initURIHandler() async {
    try {
      final initialURI = await getInitialUri();
    } on PlatformException {
      debugPrint("Failed to receive initial uri");
    }
 }

次にディープリンクを認識したときの処理を書きます。
ここでは、 ディープリンクを認識したらpushDeepLink()が呼ばれ、そのメソッド内で画面遷移が実行されます。

StreamSubscription _sub;

Future initUniLinks() async {
    _sub = linkStream.listen((String? link) {
      pushDeepLink();
    }, onError: (err) {
      debugPrint('Error occurred: $err');
    });
}

Future pushDeepLink() async {
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) {
          return TestPage();
        },
      )
    );
 }

まとめ

本記事のまとめは以下のとおりです。

  • iOSは「Associated Domains」の設定を行い、apple-app-site-associationを作成しサーバーにアップロードする。
  • AndroidはAndroidManifest.xmlにタグを追加し、assetlinks.jsonを作成しサーバーにアップロードする。
  • 「Uni Links」というプラグインを使い、公式通りに実装する。

最後までお読みいただきありがとうございました。

参考文献

https://pub.dev/packages/uni_links
https://developer.apple.com/documentation/xcode/supporting-associated-domains
https://developer.android.com/training/app-links/verify-android-applinks?hl=ja