ディープリンク
このガイドでは、さまざまなプラットフォームでディープリンクを処理するようにアプリを構成する方法について説明します。受信リンクを処理するには、次の 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 スキームに設定します。
ユニバーサルリンクがアプリで機能するようにするには、サーバーで関連ドメインも設定する必要があります。
ハイブリッドReact NativeおよびネイティブiOSアプリケーション
ハイブリッドアプリ (Swift/ObjC と React Native の両方の部分を持つ iOS アプリ) 内で React Navigation を使用している場合は、Podfile
に RCTLinkingIOS
サブスペックが見つからない可能性があります。これは、新しい 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
を開き、次の調整を行います。
- 既存の
MainActivity
でインテントを受信するために、MainActivity
のlaunchMode
をsingleTask
に設定します (これはデフォルトなので、実際には何も変更する必要がない場合があります)。 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
を構成する必要があります。
<intent-filter>
エントリにandroid:autoVerify="true"
を追加します。<intent-filter>
内の新しい<data>
エントリに、ドメインのscheme
とhost
を追加します。
追加すると、次のようになります。
<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 Links、Branch などの他のサービスも統合したい場合があります。これらは、受信リンクの通知を受け取るための独自の 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 を統合できます。