メインコンテンツにスキップ
バージョン: 6.x

ディープリンク

このガイドでは、さまざまなプラットフォームでディープリンクを処理するようにアプリを構成する方法について説明します。受信リンクを処理するには、次の 2 つのシナリオを処理する必要があります。

  1. アプリが以前に開いていなかった場合、ディープリンクは初期状態を設定する必要があります。
  2. アプリがすでに開いている場合、ディープリンクは受信リンクを反映するように状態を更新する必要があります。

React Native は、受信リンクの通知を受け取るためのLinkingを提供しています。React Navigation は、Linking モジュールと統合して、ディープリンクを自動的に処理できます。Web では、React Navigation はブラウザの history API と統合して、クライアント側の URL を処理できます。React Navigation でのリンクの構成方法の詳細については、リンクの構成を参照してください。

React Navigation の linking プロップを使用する必要はなく、Linking API を使用してディープリンクを自分で処理し、そこからナビゲートすることもできますが、多くのエッジケースを処理してくれる linking プロップを使用するよりも大幅に複雑になります。そのため、ご自身で実装することはお勧めしません。

以下に、ディープリンク統合が機能するために必要な構成について説明します。

Expoプロジェクトでのセットアップ

まず、アプリの URL スキームを指定します。これは、URL の :// の前の文字列に対応します。したがって、スキームが mychat の場合、アプリへのリンクは mychat:// になります。app.json で、scheme キーの下に文字列を追加することでスキームを登録できます。

{
"expo": {
"scheme": "mychat"
}
}

次に、ディープリンクのプレフィックスを取得するために必要な expo-linking をインストールします。

npx expo install expo-linking

次に、React Navigation が受信ディープリンクを解析するために scheme を使用するように構成しましょう。

import * as Linking from 'expo-linking';

const prefix = Linking.createURL('/');

function App() {
const linking = {
prefixes: [prefix],
};

return (
<NavigationContainer linking={linking} fallback={<Text>Loading...</Text>}>
{/* content */}
</NavigationContainer>
);
}

Linking.createURL を使用する必要がある理由は、スキームがクライアントアプリ内かスタンドアロンアプリ内かによって異なるためです。

app.json で指定されたスキームは、スタンドアロンアプリにのみ適用されます。Expo クライアントアプリでは、exp://ADDRESS:PORT/--/ を使用してディープリンクできます。ここで、ADDRESS は多くの場合 127.0.0.1 で、PORT は多くの場合 19000 です。URL は expo start を実行すると表示されます。Linking.createURL 関数は、これらを抽象化して、手動で指定する必要がないようにします。

ユニバーサルリンクを使用している場合は、ドメインもプレフィックスに追加する必要があります。

const linking = {
prefixes: [Linking.createURL('/'), 'https://app.example.com'],
};

ベアReact Nativeプロジェクトでのセットアップ

iOSでのセットアップ

mychat:// URIスキームに基づいて開くようにネイティブiOSアプリを構成しましょう。

ここに示す手順に従って、プロジェクトに RCTLinking をリンクする必要があります。受信アプリリンクをリッスンできるようにするには、プロジェクトの AppDelegate.m に次の行を追加する必要があります。

// Add the header at the top of the file:
#import <React/RCTLinkingManager.h>

// Add this inside `@implementation AppDelegate` above `@end`:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}

アプリでユニバーサルリンクを使用している場合は、次のコードも追加する必要があります。

// Add this inside `@implementation AppDelegate` above `@end`:
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}

次に、スキームをプロジェクト構成に追加する必要があります。

これを行う最も簡単な方法は、次のコマンドを実行して uri-scheme パッケージを使用することです。

npx uri-scheme add mychat --ios

手動で実行する場合は、Xcode でプロジェクト (例: SimpleApp/ios/SimpleApp.xcworkspace) を開きます。サイドバーでプロジェクトを選択し、[情報] タブに移動します。下にスクロールして [URL タイプ] を見つけ、追加します。新しい URL タイプで、識別子と URL スキームを目的の URL スキームに設定します。

Xcode project info URL types with mychat added

ユニバーサルリンクがアプリで機能するようにするには、サーバーで関連ドメインも設定する必要があります。

ハイブリッドReact NativeおよびネイティブiOSアプリケーション

ハイブリッドアプリ (Swift/ObjC と React Native の両方の部分を持つ iOS アプリ) 内で React Navigation を使用している場合は、PodfileRCTLinkingIOS サブスペックが見つからない可能性があります。これは、新しい React Native プロジェクトではデフォルトでインストールされます。これらを追加するには、Podfile が次のようになっていることを確認してください。

 pod 'React', :path => '../node_modules/react-native', :subspecs => [
. . . // other subspecs
'RCTLinkingIOS',
. . .
]

Androidでのセットアップ

Android での外部リンクを構成するには、マニフェストに新しいインテントを作成できます。

これを行う最も簡単な方法は、uri-scheme パッケージを使用することです: npx uri-scheme add mychat --android.

手動で追加する場合は、SimpleApp/android/app/src/main/AndroidManifest.xml を開き、次の調整を行います。

  1. 既存の MainActivity でインテントを受信するために、MainActivitylaunchModesingleTask に設定します (これはデフォルトなので、実際には何も変更する必要がない場合があります)。
  2. VIEW 型のアクションを使用して、MainActivity エントリ内に新しい intent-filter を追加します。
<activity
android:name=".MainActivity"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<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="mychat" />
</intent-filter>
</activity>

iOS のユニバーサルリンクと同様に、Android アプリリンクを検証して、ドメインを使用してアプリを Android の Web サイトに関連付けることもできます。まず、AndroidManifest.xml を構成する必要があります。

  1. <intent-filter> エントリに android:autoVerify="true" を追加します。
  2. <intent-filter> 内の新しい <data> エントリに、ドメインの schemehost を追加します。

追加すると、次のようになります。

<activity
android:name=".MainActivity"
android:launchMode="singleTask">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<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="mychat" />
</intent-filter>
<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="http" />
<data android:scheme="https" />
<data android:host="www.example.com" />
</intent-filter>
</activity>

次に、Digital Asset Links JSON ファイルをホストして、Web サイトとインテントフィルター間の関連付けを宣言する必要があります。

ディープリンクをテストする前に、エミュレーター/シミュレーター/デバイスでアプリを再構築してインストールしてください。

iOS でテストする場合は、次を実行します。

npx react-native run-ios

Android でテストする場合は、次を実行します。

npx react-native run-android

Expo マネージドワークフローを使用し、Expo クライアントでテストしている場合は、アプリを再構築する必要はありません。ただし、expo start (上記参照) を実行したときに表示される正しいアドレスとポート (例: exp://127.0.0.1:19000/--/) を使用する必要があります。

Expo アプリでカスタムスキームを使用してテストする場合は、expo build:ios -t simulator または expo build:android を実行してスタンドアロンアプリを再構築し、結果のバイナリをインストールする必要があります。

npx uri-scheme でのテスト

uri-scheme パッケージは、iOS と Android の両方でディープリンクをテストするために使用できるコマンドラインツールです。次のように使用できます。

npx uri-scheme open [your deep link] --[ios|android]

npx uri-scheme open "mychat://chat/jane" --ios

または、Expo クライアントを使用している場合

npx uri-scheme open "exp://127.0.0.1:19000/--/chat/jane" --ios

iOS での xcrun を使用したテスト

xcrun コマンドは、iOS シミュレーターでディープリンクをテストするために次のように使用できます。

xcrun simctl openurl booted [your deep link]

xcrun simctl openurl booted "mychat://chat/jane"

Android での adb を使用したテスト

adb コマンドは、Android エミュレーターまたは接続されたデバイスでディープリンクをテストするために次のように使用できます。

adb shell am start -W -a android.intent.action.VIEW -d [your deep link] [your android package name]

adb shell am start -W -a android.intent.action.VIEW -d "mychat://chat/jane" com.simpleapp

または、Expo クライアントを使用している場合

adb shell am start -W -a android.intent.action.VIEW -d "exp://127.0.0.1:19000/--/chat/jane" host.exp.exponent

サードパーティ統合

React Native の Linking は、ディープリンクを処理する唯一の方法ではありません。Firebase Dynamic LinksBranch などの他のサービスも統合したい場合があります。これらは、受信リンクの通知を受け取るための独自の API を提供します。

これを実現するには、React Navigation が受信リンクをサブスクライブする方法をオーバーライドする必要があります。そのためには、独自のgetInitialURL 関数とsubscribe 関数を提供できます。

const linking = {
prefixes: ['myapp://', 'https://myapp.com'],

// Custom function to get the URL which was used to open the app
async getInitialURL() {
// First, you would need to get the initial URL from your third-party integration
// The exact usage depend on the third-party SDK you use
// For example, to get the initial URL for Firebase Dynamic Links:
const { isAvailable } = utils().playServicesAvailability;

if (isAvailable) {
const initialLink = await dynamicLinks().getInitialLink();

if (initialLink) {
return initialLink.url;
}
}

// As a fallback, you may want to do the default deep link handling
const url = await Linking.getInitialURL();

return url;
},

// Custom function to subscribe to incoming links
subscribe(listener) {
// Listen to incoming links from Firebase Dynamic Links
const unsubscribeFirebase = dynamicLinks().onLink(({ url }) => {
listener(url);
});

// Listen to incoming links from deep linking
const linkingSubscription = Linking.addEventListener('url', ({ url }) => {
listener(url);
});

return () => {
// Clean up the event listeners
unsubscribeFirebase();
linkingSubscription.remove();
};
},

config: {
// Deep link configuration
},
};

上記の例と同様に、getInitialURL および subscribe オプションを使用して、最初の URL を取得し、新しい受信 URL をサブスクライブする方法を提供する任意の API を統合できます。