見出し画像

「URLでアプリを開く」を丁寧に深堀りしていく

はじめに

はじめまして、toridori開発部の髙瀬といいます。
弊社のインフルエンサー向けサービス『toridori base』『toridori ad』、そして広告主向けサービス『toridori marketing』のアプリ開発を担当しています。

昨年12月からスタートしたエンジニアブログですが、第2弾である今回は僕が書くことになりました。

■エンジニアブログ第1弾はこちら
https://note.com/toridori_inc/n/n541744a0fbd7

本記事では、僕の業務であるアプリ開発の観点から、「URLでアプリを開く」ということを深堀りしていきたいと思います。

例えば、ファッションブランドのオンラインストアで買い物をしている時、「アプリはこちら」というボタンを押すとアプリが開いた、という経験はありませんか?
このボタンには実は、アプリへと繋がるURLがリンクされているのです。
では”URLからアプリが開く”という、この動きの裏で”どのようにシステムが機能しているのか”を説明していきます。

URLでアプリを開くってどういうことなの

「入力されたURLを画面遷移の情報に変換し、その結果に従って画面遷移する」という処理が組み込まれているアプリに対して、URLを入力することを指します。
URLの受け取り手はOSによって異なります。iOSであればAppDelegateだし、AndroidならActivityです。URLを入力する時、これらの受け取り手が存在しなければ、それを確保するためにOSはアプリの立ち上げを行います。
URLを受け取ったAppDelegate(Activity)は、「入力されたURLを画面遷移の情報に変換し、その結果に従って画面遷移する」というURLハンドリング処理が組み込まれていれば、それを実行します。組み込まれていない場合は何もしません。つまり、アプリの起動のみを目的とするならばURLハンドリング処理は不要です。なぜなら、AppDelegate(Activity)に対してURLを渡した時点で、アプリの起動は達成されているからです。

アプリ用のURLってなんでこんなに種類あるの

アプリにURLを入力する経路には3種類あって、その経路によってURLの形も異なることが多いです。これは、経路ごとに期待される動作が異なるからです。

1. アプリからアプリへ
2. OSからアプリへ
3. ブラウザからアプリへ

画像1

期待される動作について、詳しく説明します。

1.アプリからアプリを開く時に期待される動作

このケースで期待される動作は、当たり前ですが

URLに従って画面遷移できる

ことです。

2.OSからアプリを開く時に期待される動作

このケースでは、1番の経路で期待される「URLに従って画面に遷移できる」に加えて、

アプリがインストールされていなければ、AppStore(PlayStore)アプリを起動して、該当アプリのインストールページに遷移できる

という動作が期待されます。なぜなら、1番の経路とは違いURLの入力元がアプリではなく、アプリがインストール済みである保証がないからです。アプリがインストールされていない場合、AppDelegate(Activity)を確保するためのアプリ起動が行えないので、URLの受け渡しは失敗します。
2番の経路で期待される動作はもう1つあって、それは

アプリのインストールに成功したら、そのインストール後の初回起動時までURLの受け渡しを保留にできる

ことです。

3.ブラウザからアプリを開く時に期待される動作

このケースでも、2番の経路と同じ動作が期待されます。この経路で新しく期待される動作は、

アプリがインストールされていない時、そのアプリのOSに従って、PlayStoreを起動するかAppStoreを起動するか決めることができる

です。これは、大抵のブラウザが複数のOS上で動作できるためです。
ブラウザからアプリを開く時、そのブラウザがiOSもしくはAndroidで動作している保証はありません。よって、ブラウザからアプリを開くときには次の動作も期待されます。

iOSでもAndroidでもないプラットフォームで開かれたときは、アプリではなくWebページに遷移できる

アプリを開けなかったときのfallbackというイメージがわかりやすいかもしれません。

アプリ用のURLの種類について具体的に詳しく

上のセクションでは、

1. アプリからアプリへ
2. OSからアプリへ
3. ブラウザからアプリへ

という3つの経路でアプリが開かれることを説明しました。これらの経路で期待される動作は、それぞれ

1. CustomUrlScheme
2. UniversalLInk(iOS)やAppLink(Android)
3. Firebase Dynamic Link

という方法を用いて達成されることが多いです。これらについて説明します。

1.CustomUrlScheme

1番の経路では、単に

URLに従って画面遷移できる

という動作が期待されます。これを実現するときによく使われるのがCustomUrlSchemeです。
ところで、初めの方で説明したとおり、URLのハンドリング処理の具体的な実装はデベロッパに委ねられています。従って、CustomUrlSchemeの具体的な仕様もデベロッパに一任されます。
CustomUrlSchemeという名前がついているものの、それは単に

1. URLの仕様を決める
2. URLのハンドリング処理を実装する
3. OSから受け取るURL、受け取らないURLを決める

をという工程でデベロッパが作成する任意のURLです。
一般には、URLのスキームをアプリ独自のものにし、hostとpathに画面を特定する情報を埋め込むことが多いです。


instagram://camera

twitter://post?message=hello%20world

もはやURLですらなくても良い気がしてきますが、3番の「OSから受け取るURL、受け取らないURLを決める」という工程において、

●iOS: 受け取るURLのSchemeをInfo.plistに書き込む
●Android: 受け取るURLのScheme, Host, pathの組み合わせをAndroidManifestに書き込む

という操作が求められるので、URLの形式は保つ必要がありそうです。
CostomUrlSchemeの動作を図にすると以下のようになります。これだけじゃなんのこっちゃって感じですね(次の説明のために一応載せました)

画像2

2.UniversalLinkやAppLink

2番の経路で求められる

アプリがインストールされていなければ、AppStore(PayStore)アプリを起動して、該当アプリのインストールページに遷移できる

動作を実現するための方法です。
予め用意しておいたCustomUrlSchemeをパラメータとして持つURLを発行します。このURLが開かれた時、アプリがインストール済みであればそのパラメータがAppDelegate(Activity)に渡されます。インストールされていなければ、AppStore(PlayStore)に遷移します。
UniversalLinkの動作を図にすると以下のようになります。UniversalLinkを開くと、OSはアプリがインストール済みかどうかをチェックし、インストール済みであればそのアプリにCustomUrlSchemeを渡します。そうでなければ、ストアアプリのインストールページを開きます。

画像3

UniversalLinkの問題点は、iOSでしか開けないことです。AppLinkも同様です。
両方のURLを掲載すれば解決する問題ではありますが、それを1つにまとめたいと思った時、次に説明するFirebase Dynamic Linkが役に立ちます。

3.Firebase Dynamic Link

3番の経路で求められる

アプリがインストールされていない時、そのアプリのOSに従って、
PlayStoreを起動するかAppStoreを起動するか決めることができる

iOSでもAndroidでもないプラットフォームで開かれたときは、
アプリではなくWebページに遷移できる

を実現するための方法です。
Firebase Dynamic Linkを使うときは、最低限ブラウザで開ける、かつ、希望するOS上のアプリでハンドリング可能なhttps形式のURLが必要です。
Firebase Dynamic Linkを使用するデベロッパは、まず、https形式のWebページを1つ用意します。次に、「そのWebページが仮にアプリで開かれるとしたら」を想定し、そのWebページのURLのハンドリング処理をアプリに組み込みます。そうすると、Firebase Dynamic Linkは「その環境に適した遷移先」を判断してくれるようになります。
ここで言う環境とは、

●アプリをインストール済みな状態のAndroid
●アプリをインストール済みな状態のiOS
●アプリをインストールしていない状態のAndroid
●アプリをインストールしていない状態のiOS
●Windows
●Mac

等が挙げられます。「任意の環境で開ける1つのURL」をイメージするとわかりやすいかもしれません。
Firebase Dynamic Linkの動作を図にすると以下のようになります。一気に複雑になりましたね...
便宜上、URLと書いていますが、これは最低限ブラウザで開ける、かつ、希望するOS上のアプリでハンドリング可能なhttps形式のURLを指します。

画像4

結局DeepLinkってなんなの?

結局の所、アプリを開くというコンテキストの上では、「アプリを起動できるURL」の総称だと思ってます。
具体的な技術の名前ではなく総称です。実際にDeepLinkを使用する場面では、UniversalLinkだったり、Firebase Dynamic Linkだったり、の技術が用いられます。

実際にどんなふうに使われるか教えてよ

次の3つのURLについて、想定される使われ方を説明します。

●CustomUrlScheme
●Firebase Dynamic Link
●Firebase Dynamic Linkに登録するWebページ用URL

CustomUrlScheme

次のようなユースケースが想定されます。

●アプリ内のテキストUIにリンクを仕込んで画面遷移させたい時
●特定の画面に遷移できるPush通知を発行した時
●特定の画面に遷移できるボタンを持つFirebase In App Messagingを発行したい時

特定の画面に遷移できるボタンを持つFirebase In App Messagingを発行したい時
いずれのユースケースも、アプリがインストールされていることが保証されています。これが保証されないユースケースでは、CustomUrlSchemeは利用できません。
ところで、アプリを開発していると、開発環境のアプリと本番環境のアプリを別アプリ化したい事がよくあります。目的は1つで、同じ端末上に開発環境のアプリと本番環境のアプリを同居させたいからです。
このとき、開発環境のアプリと本番環境のアプリの両方で同じCustomUrlSchemeを登録していた場合、CustomUrlSchemeの入力先となるアプリが一意に決まらない問題が発生します(登録についてはこちらを参照)。
CustomUrlSchemeの入力先となるアプリが一意に決まらない場合、iOSでは、CustomUrlSchemeを開いた後の挙動が不安定になってしまいます。これを避けるため、登録するCustomUrlSchemeのSchemeは、開発環境と本番環境で分けることが望ましいです。なお、Androidでは、CustomUrlSchemeの入力先が一意に決まらなかったときにどのアプリを開くか選択することができるので、この問題は発生しません。

Firebase Dynamic Link

次のユースケースで使用することが想定されます。

●アプリ外の任意の場所から特定の画面に遷移させたい時

CustomUrlSchemeが使えない時、と言い換えても良いです。
前述の通り、Firebase Dynamic Linkは環境の差分を吸収できる1つのURLです。これを使うことで、

●PCで開いてもバグらないようにする
●アプリ持ってない人が開いたらインストールページに遷移させる
●ユーザのOS(iOS, Android)に応じて遷移先を分ける

という動作をまとめて達成することができます。

おわりに

いかがでしたか?
今回は僕の業務であるアプリ開発の観点から、「URLでアプリを開く」ということを深堀りしてみました。

toridoriの開発部はサービスの機能を最適化し、企業やインフルエンサー、”誰もがより使いやすいサービス”を目指して、日々試行錯誤を繰り返しながらみなさんのもとへお届けしています。

そんなtoridori開発部では新メンバーを募集中です。
インフルエンサーマーケティングという、この先5年間で市場規模が2倍以上になると言われている成長業界の中で、時代を創っていく企業のメンバーとして、一緒に働きませんか?

画像5

いいなと思ったら応援しよう!

ピックアップされています

エンジニアブログ

  • 16本

コメント

1

こちらの解説すごくわかりやすかったです!
おかげさまでSvelteNativeでの開発がかなりはかどりましたありがとうございます😌

ログイン または 会員登録 するとコメントできます。
「URLでアプリを開く」を丁寧に深堀りしていく|株式会社トリドリ(toridori)
word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word

mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1