React NativeでURL Schemeを使って任意のComponentを表示する方法を紹介します。
ネイティブ側設定
ネイティブの設定はReact Nativeを使わない場合と同じです。
myapp://open
から始まるURL Schemeを使用する場合は以下のように設定します。
Android
AndroidManifest.xmlのMainActivityのactivity
タグ内の要素として以下の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:host="open"
android:scheme="myapp" />
</intent-filter>
iOS
Xcodeでプロジェクトを開き, 左のツリーのプロジェクトのルートを選択、Infoをクリックし、一番下のURL Typesを追加します。
またAppDelegate.mに以下のコードを追記します。
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}
// ユニバーサルリンク使うならこっちも (https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html).
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
React Native側
App.jsのような最初に起動するコンポーネントに以下のコードを追加します。
iosとandroidでURLの取得方法が異なります。そのためプラットフォームによって分岐しています。
componentDidMount () {
if (Platform.OS === 'android') {
// androidはこのタイミングで起動されたURLを取得できる
Linking.getInitialURL()
.then(url => {
if (url) {
this.openFromUrlScheme(url)
}
})
.catch(e => {
console.log(e)
})
} else if (Platform.OS === 'ios') {
// iosの場合はハンドラを経由する必要があるので追加
Linking.addEventListener('url', this.handleOpenURL)
}
}
componentWillUnmount () {
Linking.removeEventListener('url', this.handleOpenURL)
}
handleOpenURL = event => {
if (event.url) {
this.openFromUrlScheme(event.url)
}
}
//
openFromUrlScheme = url => {
console.log(url)
const parsedUrl = parse(url, true)
if (parsedUrl.protocol === 'myapp:') {
// 任意の画面を開く処理
// この例はreact-native-router-fluxでdebugMenuシーンを開くためのコード
Actions.debugMenu()
}
}
componentWillUnmount () {
Linking.removeEventListener('url', this.handleOpenURL)
}
handleOpenURL = event => {
if (event.url) {
this.openFromUrlScheme(event.url)
}
}
//
openFromUrlScheme = url => {
console.log(url)
const parsedUrl = parse(url, true)
if (parsedUrl.protocol === 'myapp:') {
// 任意の画面を開く処理
// この例はreact-native-router-fluxでdebugMenuシーンを開くためのコード
Actions.debugMenu()
}
}
参考
https://medium.com/react-native-training/deep-linking-your-react-native-app-d87c39a1ad5e