Deep Linkとは
Deep Linkは、モバイルアプリケーション内の特定のコンテンツに直接リンクすることができるリンクです。たとえば、特定の製品ページ、チュートリアル、または検索結果に直接リンクすることができます。Deep Linkは、ユーザーがアプリを開いている場合にのみ機能します。
ディープリンク(Deep link)、ディープリンキング(Deep linking)は、あるウェブページから他のウェブサイトのトップページ以外の各コンテンツ(ウェブページ・画像等)に直接ハイパーリンクを張ること。他サイトの画像などを自サイト内に直接参照(「表示」など)させること(→直リンク)とは異なり、単にリンクアンカーによりポインタを示すのみの行為を指す。
ここで実現したいのはDeep Link でURLリンクをタップしてFlutterアプリを開くことです。
Deep Linkの種類
-
Custom URL Scheme
アプリ固有のスキーム(例: myapp://)を用いたリンク形式です。
例: myapp://product/12345 -
Universal Links
Apple(iOS)が提供している アプリとウェブをシームレスに連携する仕組み のことです。- ユーザーが Safari やメールなどで 特定の URL をタップしたとき
- その URL がアプリに関連付けられていれば、ブラウザではなく直接アプリが開く
- アプリが未インストールなら、通常の Web ページが開く
-
App Links
Android が提供する ウェブ URL とアプリを関連付ける仕組み。
ユーザーがブラウザやメールアプリでリンクをタップしたときに:- アプリがインストールされていれば 直接アプリが起動
- インストールされていなければ 通常の Web ページが開く
-
Deferred Deep Link
ユーザーが アプリをまだインストールしていない状態でリンクを踏んだ場合でも、
アプリをインストールした後に 元々踏んだリンク先のページに遷移できる仕組み のことです- ユーザーがリンクをクリック
- アプリ未インストールの場合 → ストアにリダイレクト
- インストール完了 → アプリ初回起動時にリンク情報(パラメータなど)を受け取り
- 直接リンク先ページ(キャンペーンページなど)を表示
代表例:Adjust / AppsFlyer / Branch.io(モバイル計測プラットフォーム)
Custom URL Scheme
Android
android/app/src/main/AndroidManifest.xml
<activity ...>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="schemeName"
android:host="hostName" />
</intent-filter>
</activity>
iOS
ios/Runner/Info.plist
<?xml ...>
<!-- ... other tags -->
<plist>
<dict>
<!-- ... other tags -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>[ANY_URL_NAME]</string>
<key>CFBundleURLSchemes</key>
<array>
<string>[YOUR_SCHEME]</string>
</array>
</dict>
</array>
<!-- ... other tags -->
</dict>
</plist>
上記の設定でdeep Linkは「shcemeName://hostName
」となり、それを呼び出すことで、アプリを開くことができます。
呼び出しにパラメーターを追加したい場合、末尾に?parameter=para
をつけます。
Universal Links
-
Apple Bundle IDの設定
Apple開発アカウントに登録して、該当Apple Bundle IDのCapabilitiesのAssociated Domains
をENABLEにしてください。
-
iOS Capabilitiesの追加
- Runner.entitlementファイルの場合
ソースコードで追加する場合、下記のソースを追加してください。
/ios/Runner/Runner.entitlements
<key>com.apple.developer.associated-domains</key> <array> <string>applinks:your-domain</string </array>
- Runner.entitlementファイルの場合
-
サーバーでapple-app-site-associationファイルを配置
サーバーのルートディレクトリに.well-known
フォルダを作成し、ファイル名はapple-app-site-associationのjsonファイルを配置する{ "applinks": { "apps": [], "details": [ { "appID": "TEAMID.BUNDLEID", "paths": ["*"] } ] } }
注意点
メタデータのcontent-Typeはappliciaton/json
であること
拡張子なし
App Links
- android/app/src/main/AndroidManifest.xml
<!-- Deep Link(HTTPS 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" /> <data android:scheme="https" android:host="your-domain.com" /> </intent-filter>
- サーバーのルートディレクトリに.well-knownフォルダを作成し、ファイル名はassetlinks.jsonファイルを配置する
sha256_cert_fingerprintsは下記のコマンドで確認できる
[{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.example.deeplink_cookbook", "sha256_cert_fingerprints": ["FF:2A:CF:7B:DD:CC:F1:03:3E:E8:B2:27:7C:A2:E3:3C:DE:13:DB:AC:8E:EB:3A:B9:72:A1:0E:26:8A:F5:EC:AF"] } }]
keytool -list -v -keystore my-release-key.keystore -alias my-key-alias -storepass xxxxx -keypass xxxxx
エミュレータにて動作確認
iOS
xcrun simctl openurl booted "schemeName://hostName/?parameter=para"
xcrun simctl openurl
コマンドでDeep Linkを開く際に、クエリパラメーターを含める場合、URLエンコードが必要です。つまり、?や=などの特殊文字をエンコードする必要があります。
従って、エンコードされたURLを使用することをお勧めします。
上記のコマンドの"schemeName://hostName/?parameter=para"
の二重引用符は忘れないように!
Android
adb -e shell 'am start -W -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d "schemeName://hostName/?parameter=para"'
実機確認する場合はadb -e
をadb -d
に変えれば呼び出せます。
使うパッケージ
dependencies:
app_links: ^6.4.0
パラメーターの取得
Deep Linkで呼び出された場合、下記のソースでリンクURLやパラメーターを取得できます。
import 'package:app_links/app_links.dart';
StreamSubscription _sub;
Future<void> initUniLinks(BuildContext context) async {
final appLinks = AppLinks();
_sub = appLinks.uriLinkStream.listen(
(Uri? uri) async {
if (uri != null) {
//さっき設定したスキームをキャッチしてここが走る。
String? authCode = uri.queryParameters['code'];
if (authCode != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
authVerifySAML(authCode, context);
});
}
}
},
onError: (err) {
logger.e(err);
},
);
}
結果:
flutter: para
参考