深度連結
本指南將說明如何設定您的應用程式以處理各種平台上的深度連結。若要處理接收的連結,您需要處理兩種情況
- 如果應用程式尚未開啟,深度連結必須設定初始狀態
- 如果應用程式已經開啟,深度連結必須更新現有狀態以反映接收的連結
React Native 提供 連結
以接收有關接收連結的通知。React Navigation 可以整合 Linking
模組以自動處理深度連結。在網頁上,React Navigation 可以整合瀏覽器的 歷程
API 以在用戶端處理 URL。請參閱 設定連結 以進一步瞭解如何設定 React Navigation 中的連結。
使用 React 導航時,您不必使用 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
Налаштуємо рідну програму iOS для відкриття на основі схеми URI mychat://
.
Вам потрібно прив'язати 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
)。在側邊欄中選取專案,然後移至資訊標籤。向下捲動至「網址類型」並新增一個。在新網址類型中,將識別碼和網址方案設定為您想要的網址方案。
為確保通用連結可以在您的應用程式中運作,您還需要在伺服器上設定 關聯式網域。
混合 React Native 和原生 iOS 應用程式
如果您是在混合應用程式中使用 React Navigation(一個同時包含 Swift/ObjC 和 React Native 的 iOS 應用程式),您可能會在 Podfile
中找不到 RCTLinkingIOS
子規格,此子規格會在新的 React Native 專案中預設安裝。若要新增這項子規格,請確保您的 Podfile
如下所示
pod 'React', :path => '../node_modules/react-native', :subspecs => [
. . . // other subspecs
'RCTLinkingIOS',
. . .
]
在 Android 上設定
若要在 Android 中設定外部連結,您可以在宣告檔中建立新的 intent。
最簡單的方法是使用 uri-scheme
套件:npx uri-scheme add mychat --android
。
如果您想手動新增,請開啟 SimpleApp/android/app/src/main/AndroidManifest.xml
,並進行下列調整
- 將
MainActivity
的launchMode
設定為singleTask
以在現有的MainActivity
上接收 intent(這是預設值,因此您可能不需要實際變更任何設定)。 - 在
MainActivity
項目中新增新的intent-filter
,並使用VIEW
型式動作
<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 應用程式連結。首先,您需要設定 AndroidManifest.xml
- 新增
android:autoVerify="true"
到您的<intent-filter>
項目中。 - 在
<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>
然後,您需要 宣告關聯式,讓您的網站和 intent 過濾器之間產生關聯,方法是主機數位資產連結 JSON 檔案。
測試深入連結
在測試深入連結之前,請務必在您的模擬器/模擬程式/裝置上重新建置並安裝應用程式。
如果您在 iOS 上測試,請執行
npx react-native run-ios
如果您在 Android 上測試,請執行
npx react-native run-android
如果您使用 Expo 管理式工作流程並在 Expo 用戶端上進行測試,您不必重新建置 app。然而,您需要使用正確的位址和埠,這些位址和埠將在您執行「expo start」時印出(見上文),例如「exp://127.0.0.1:19000/--/」。
如果您想在您的 Expo app 中,使用自訂的 scheme 進行測試,您需要執行「expo build:ios -t simulator」或「expo build:android」來重新建置您的獨立 app,然後安裝產生的二進制檔。
使用「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 的「連結」並非處理深度連結的唯一方法。您可能還想整合其他服務,例如 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
},
};
類似於上述範例,您可以整合任何 API,這個 API 提供取用初始網址,以及使用「getInitialURL」和「subscribe」選項訂閱新的進來網址。