Linking
Linking
提供您一個通用介面,用於與應用程式連結的輸入和輸出互動。
每個連結 (URL) 都有一個 URL Scheme,有些網站以 https://
或 http://
作為前綴,而 http
就是 URL Scheme。我們簡稱它為 scheme。
除了 https
之外,您可能也熟悉 mailto
scheme。當您開啟一個使用 mailto scheme 的連結時,您的作業系統會開啟已安裝的郵件應用程式。同樣地,也有用於撥打電話和發送簡訊的 scheme。請閱讀以下關於內建 URL scheme 的更多資訊。
就像使用 mailto scheme 一樣,可以透過使用自訂 URL scheme 連結到其他應用程式。例如,當您收到來自 Slack 的 Magic Link 電子郵件時,Launch Slack 按鈕是一個錨點標籤,其 href 看起來像這樣:slack://secret/magic-login/other-secret
。與 Slack 類似,您可以告訴作業系統您想要處理一個自訂 scheme。當 Slack 應用程式開啟時,它會收到用於開啟它的 URL。這通常被稱為深度連結。請閱讀更多關於如何取得應用程式的深度連結。
自訂 URL scheme 不是在行動裝置上開啟應用程式的唯一方法。例如,如果您想透過電子郵件發送一個連結給某人,以便在行動裝置上開啟,使用自訂 URL scheme 並不理想,因為使用者可能會在桌上型電腦上開啟電子郵件,而連結將無法運作。相反地,您應該使用標準的 https
連結,例如 https://www.myapp.io/records/1234546
。在行動裝置上,這些連結可以被設定為開啟您的應用程式。在 Android 上,此功能稱為 Deep Links,而在 iOS 上,則稱為 Universal Links。
內建 URL Scheme
如簡介中所述,每個平台都存在一些用於核心功能的 URL scheme。以下是一個非詳盡的列表,但涵蓋了最常用的 scheme。
Scheme | 描述 | iOS | Android |
---|---|---|---|
mailto | 開啟郵件應用程式,例如:mailto: support@expo.io | ✅ | ✅ |
tel | 開啟電話應用程式,例如:tel:+123456789 | ✅ | ✅ |
sms | 開啟簡訊應用程式,例如:sms:+123456789 | ✅ | ✅ |
https / http | 開啟網頁瀏覽器應用程式,例如:https://expo.io | ✅ | ✅ |
啟用深度連結
如果您想在您的應用程式中啟用深度連結,請閱讀以下指南
- Android
- iOS
關於如何在 Android 上新增深度連結支援的說明,請參考 Enabling Deep Links for App Content - Add Intent Filters for Your Deep Links。
如果您希望在 MainActivity 的現有實例中接收 intent,您可以將 MainActivity 的 launchMode
在 `AndroidManifest.xml` 中設定為 singleTask
。請參閱 <activity>
文件以取得更多資訊。
<activity
android:name=".MainActivity"
android:launchMode="singleTask">
注意: 在 iOS 上,您需要將
LinkingIOS
資料夾新增到您的標頭搜尋路徑中,如 此處 步驟 3 所述。如果您也想在應用程式執行期間監聽傳入的應用程式連結,您需要將以下幾行程式碼新增到您的*AppDelegate.m
中
// iOS 9.x or newer
#import <React/RCTLinkingManager.h>
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
如果您以 iOS 8.x 或更舊版本為目標,您可以改用以下程式碼
// iOS 8.x or older
#import <React/RCTLinkingManager.h>
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}
如果您的應用程式使用 Universal Links,您也需要新增以下程式碼
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
處理深度連結
有兩種方法可以處理開啟您應用程式的 URL。
1. 如果應用程式已開啟,應用程式將被前景化,並觸發 Linking 'url' 事件
您可以使用 `Linking.addEventListener('url', callback)` 處理這些事件 - 它會使用連結的 URL 呼叫 `callback({url})`
2. 如果應用程式尚未開啟,它將被開啟,並且 URL 將作為 initialURL 傳入
您可以使用 `Linking.getInitialURL()` 處理這些事件 - 如果有的話,它會返回一個 Promise,該 Promise 會解析為 URL。
範例
開啟連結和深度連結 (通用連結)
- TypeScript
- JavaScript
開啟自訂設定
- TypeScript
- JavaScript
取得深度連結
- TypeScript
- JavaScript
發送 Intents (Android)
- TypeScript
- JavaScript
參考
方法
addEventListener()
static addEventListener(
type: 'url',
handler: (event: {url: string}) => void,
): EmitterSubscription;
透過監聽 url
事件類型並提供處理常式,為 Linking 變更新增處理常式。
canOpenURL()
static canOpenURL(url: string): Promise<boolean>;
判斷已安裝的應用程式是否可以處理給定的 URL。
此方法返回一個 Promise
物件。當確定給定的 URL 是否可以被處理時,promise 會被解析,並且第一個參數是它是否可以被開啟。
如果無法檢查 URL 是否可以開啟,或者在以 Android 11 (SDK 30) 為目標時,如果您沒有在 `AndroidManifest.xml` 中指定相關的 intent 查詢,則 `Promise` 將在 Android 上拒絕。同樣地,在 iOS 上,如果您沒有在 `Info.plist` 內的 `LSApplicationQueriesSchemes` 鍵中新增特定的 scheme(請參閱下方),promise 將會拒絕。
參數
名稱 | 類型 | 描述 |
---|---|---|
url 必填 | 字串 | 要開啟的 URL。 |
對於網頁 URL,必須相應地設定協定(
"http://"
、"https://"
)!
此方法在 iOS 9+ 上有限制。來自 Apple 官方文件
- 如果您的應用程式是針對較舊版本的 iOS 連結的,但在 iOS 9.0 或更高版本中執行,您可以調用此方法最多 50 次。達到該限制後,後續的調用始終解析為 `false`。如果使用者重新安裝或升級應用程式,iOS 將重置限制。
從 iOS 9 開始,您的應用程式也需要在 `Info.plist` 內提供 `LSApplicationQueriesSchemes` 鍵,否則 `canOpenURL()` 將始終解析為 `false`。
在以 Android 11 (SDK 30) 為目標時,您必須在 `AndroidManifest.xml` 中指定您要處理的 scheme 的 intent。常見 intent 的列表可以在 這裡 找到。
例如,為了處理 `https` scheme,需要將以下內容新增到您的 manifest 中
<manifest ...>
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https"/>
</intent>
</queries>
</manifest>
getInitialURL()
static getInitialURL(): Promise<string | null>;
如果應用程式啟動是由應用程式連結觸發的,它將提供連結 URL,否則它將提供 `null`。
為了支援 Android 上的深度連結,請參考 https://developer.android.com/training/app-indexing/deep-linking.html#handling-intents
當遠端 JS 除錯處於活動狀態時,getInitialURL 可能會返回 `null`。停用除錯器以確保它被傳遞。
openSettings()
static openSettings(): Promise<void>;
開啟「設定」應用程式並顯示應用程式的自訂設定(如果有的話)。
openURL()`
static openURL(url: string): Promise<any>;
嘗試使用任何已安裝的應用程式開啟給定的 url
。
您可以使用其他 URL,例如位置(例如 Android 上的 "geo:37.484847,-122.148386" 或 iOS 上的 "https://maps.apple.com/?ll=37.484847,-122.148386")、聯絡人或任何可以使用已安裝應用程式開啟的其他 URL。
此方法返回一個 Promise
物件。如果使用者確認開啟對話框或 URL 自動開啟,則 promise 會被解析。如果使用者取消開啟對話框或沒有為 URL 註冊的應用程式,則 promise 會被拒絕。
參數
名稱 | 類型 | 描述 |
---|---|---|
url 必填 | 字串 | 要開啟的 URL。 |
如果系統不知道如何開啟指定的 URL,此方法將會失敗。如果您傳入的是非 http(s) URL,最好先檢查 `canOpenURL()`。
對於網頁 URL,必須相應地設定協定(
"http://"
、"https://"
)!
此方法在模擬器中的行為可能有所不同,例如
"tel:"
連結無法在 iOS 模擬器中處理,因為無法存取撥號程式應用程式。
sendIntent()
Android
static sendIntent(
action: string,
extras?: Array<{key: string; value: string | number | boolean}>,
): Promise<void>;
啟動具有 extras 的 Android intent。
參數
名稱 | 類型 |
---|---|
action 必填 | 字串 |
extras | Array<{key: string, value: string | number | boolean}> |