React Native Tech Blog

supported by maricuru (旧maricuru tech blogです)

【React Native】【Expo】ディープリンクを実装する

こんにちは、maricuruのワダ(@takahi5)です。

弊社maricuruは今までアプリのみでしたが、現在Web版も開発しています。
Webとアプリをスムーズに移動できるようにと、ディープリンクを実装してみました♪

今回はExpoでのディープリンクの実装についてご紹介したいと思います。

f:id:wasan:20181101134001p:plain

ディープリンクとは?

特定のアプリに遷移させることの出来るリンクのことです。

例えば、retty://というURLをiPhoneで叩くと、Rettyアプリが起動します。

「ブラウザ➔アプリ」の遷移だけでなく、
「アプリ➔アプリ」の遷移も可能です。

ただRettyアプリがインストールされてないと、エラーになります。
ストアに飛ばすなどのカスタマイズはできないので注意が必要です。

ディープリンクの実装

基本的には Linking に書いてありますが、
要所を整理して説明したいと思います♪

アプリへのリンク

ローカルのシミュレーター、Expo Clientアプリ、スタンドアロンビルド、でリンクURLが異なります。

ローカルのシミュレーターの場合

macローカルのiOSシミュレーターなどで立ち上げる場合です。

exp://localhost:19000 にアクセスするとExpo clientアプリで対象のアプリが起動します。

publish済みのアプリをExpo Clientアプリで開く場合

publish済みのアプリを、iPhoneなりAndroid実機のExpo Clientアプリで開く場合です。

まずpublishしたときのログを確認しましょう。
こんな感じだったとします。

[16:46:56] Published
[16:46:56] Your URL is

https://exp.host/@awesome-company/myapp

この場合は、exp://exp.host/@awesome-company/myapp にアクセスすると、Expo Clientアプリで先ほどpublishしたアプリが開かれるはずです。

スタンドアロンビルドの場合

いよいよ本番向けのスタンドアロンビルドの場合です。

まずapp.jsonに設定が必要です。

// app.json
{
  "expo": {
    "scheme": "myapp"
  }
}

こうすればmyapp://のURLでこのアプリが起動されるようになります!

アプリ起動後の処理

ここまでの実装だと、単にアプリが開くだけです。

本来なら特定の記事やコンテンツを開きたいですね。

URLから起動した場合のアプリ内でのハンドリング

どのようなURLから起動したかを取得

URLをパース

然るべき処理をする

のような流れになります。

まずは起動URLを取得してみましょう。

アプリがすでに起動している場合のハンドリング

Expo.Linking.addEventListener()でコールバックイベントを登録しておきます。

componentDidMount() {
  Expo.Linking.addEventListener('url', _handleOpenURL);
}

function _handleOpenURL(event) {
  console.log(event.url);
}

アプリが起動してない場合のハンドリング

Expo.Linking.getInitialURL()で起動時に渡されたURLを取得できます。

async componentDidMount() {
  const url = await Expo.Linking.getInitialURL();
  console.log(url);
}

URLのパース

情報を渡すにはmyapp://の後に情報を付け足せばOKです。
たとえば myapp://articles/4334にしたとします。

受け取ったURLはurl.parse関数などを使ってパースするとよいでしょう。

import url from 'url';

(中略)

function _handleOpenURL(event) {
  const parsedUrl = url.parse(targetUrl);
  console.log(parsedUrl);
}

パース結果はこのような感じです。

"host": "articles",
"hostname": "articles",
"href": "myapp://articles/4334",
"path": "/4334",
"pathname": "/4334",
"port": null,
"protocol": "myapp:",
"query": null,

このデータを使って、然るべきページに遷移するなどすればよさげですね!

補足(Universal Links)

今回説明したディープリンクは、Custom URL Schemeと言われるものらしいです。

それに変わる手法としてUniversal LinksというのがiOS9から導入されています。

Custom URL Schemがmyapp://articles/999のような特殊URLなのに対して、
Universal Linksはhttps://myapp.com/articles/999のようなhttps経由でアプリを開くことができます。

アプリがない場合は普通にhttps://myapp.com/articles/999のWebページが開かれます。
ウェブサイトもあるならこっちのほうが良さげですね。

ちなみにExpoではBranch というAPIを使えば実現できるらしいです。
まだα版でDangerZoneって書いてありますが...

いずれこのBranchも試してみたいと思います♪