链接处理
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
Linking 提供了一个通用接口,用于处理应用内外的链接交互。
每个链接(URL)都包含 URL Scheme。例如网站通常以 https:// 或 http:// 开头,其中的 http 就是 URL Scheme。为简洁起见,我们将其简称为 scheme。
除了 https,你可能还熟悉 mailto scheme。当你打开带有 mailto scheme 的链接时,操作系统会启动已安装的邮件应用。类似地,还有用于拨打电话和发送短信的 scheme。更多关于内置 URL scheme 的信息请见下文。
就像使用 mailto scheme 一样,通过自定义 URL scheme 也可以链接到其他应用。例如当你收到 Slack 的 魔法链接 邮件时,启动 Slack 按钮实际上是一个锚点标签,其 href 类似于:slack://secret/magic-login/other-secret。和 Slack 类似,你可以告知操作系统希望处理自定义 scheme。当 Slack 应用打开时,它会收到用于启动它的 URL。这通常被称为深度链接(deep linking)。了解如何获取深度链接进入你的应用。
自定义 URL scheme 并非在移动端打开应用的唯一方式。例如,如果你想通过邮件发送移动端可打开的链接,使用自定义 URL scheme 并不理想——因为用户可能在桌面端打开邮件,导致链接失效。此时应该使用标准的 https 链接,例如 https://www.myapp.io/records/1234546。在移动端,这些链接可以配置为直接打开你的应用。在 Android 上此功能称为 深度链接(Deep Links),而在 iOS 上则称为 通用链接(Universal Links)。
内置 URL 方案
如引言所述,各平台都内置了实现核心功能的 URL scheme。以下是非详尽列表,但涵盖了最常用的 scheme。
| Scheme | Description | iOS | Android |
|---|---|---|---|
mailto | Open mail app, eg: mailto: hello@world.dev | ✅ | ✅ |
tel | Open phone app, eg: tel:+123456789 | ✅ | ✅ |
sms | Open SMS app, eg: sms:+123456789 | ✅ | ✅ |
https / http | Open web browser app, eg: https://expo.dev | ✅ | ✅ |
启用深度链接
如需在应用中启用深度链接,请阅读以下指南:
- Android
- iOS
For instructions on how to add support for deep linking on Android, refer to Enabling Deep Links for App Content - Add Intent Filters for Your Deep Links.
If you wish to receive the intent in an existing instance of MainActivity, you may set the launchMode of MainActivity to singleTask in AndroidManifest.xml. See <activity> documentation for more information.
<activity
android:name=".MainActivity"
android:launchMode="singleTask">
NOTE: On iOS, you'll need to add the
LinkingIOSfolder into your header search paths as described in step 3 here. If you also want to listen to incoming app links during your app's execution, you'll need to add the following lines to your*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];
}
If you're targeting iOS 8.x or older, you can use the following code instead:
// 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];
}
If your app is using Universal Links, you'll need to add the following code as well:
- (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) 处理这些事件 - 该方法会调用 callback({url}) 并传入链接的 URL
2. 若应用未打开,应用将被启动且 URL 会作为 initialURL 传入
可通过 Linking.getInitialURL() 处理这些事件 - 它返回一个 Promise,解析后得到 URL(如果有的话)
示例
打开链接与深度链接(通用链接)
- TypeScript
- JavaScript
打开自定义设置
- TypeScript
- JavaScript
获取深度链接
- TypeScript
- JavaScript
发送 Intent(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 会得到解析(resolved),其第一个参数表示该 URL 是否可被打开
在 Android 平台上,如果无法检查 URL 是否可打开,或者当目标为 Android 11(SDK 30)却未在 AndroidManifest.xml 中声明相关 intent 查询时,Promise 会拒绝执行。类似地,在 iOS 上若未将特定 scheme 添加到 Info.plist 的 LSApplicationQueriesSchemes 键中(参见下文),Promise 也会拒绝执行。
参数:
| Name | Type | Description |
|---|---|---|
| url Required | string | The URL to open. |
对于网页 URL,必须正确设置协议(
"http://"或"https://")!
此方法在 iOS 9+ 上有使用限制。根据苹果官方文档:
- 若应用链接到较早的 iOS 版本但在 iOS 9.0 或更高版本上运行,此方法最多可调用 50 次。达到限制后,后续调用将始终返回
false。如果用户重装或升级应用,iOS 会重置该限制。从 iOS 9 开始,应用必须在
Info.plist中提供LSApplicationQueriesSchemes键,否则canOpenURL()将始终返回false。
当目标为 Android 11(SDK 30)时,必须在
AndroidManifest.xml中声明要处理的 scheme 对应的 intent。常见 intent 列表可参考此处。例如要处理
httpsscheme,需在清单中添加:<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" 或 "https://maps.apple.com/?ll=37.484847,-122.148386" 在 iOS 上)、联系人卡片或其他可由已安装应用打开的 URL。
该方法返回 Promise 对象。若用户确认打开对话框或 URL 自动打开,则 Promise 解析成功;若用户取消操作或没有注册应用处理该 URL,则 Promise 拒绝执行。
参数:
| Name | Type | Description |
|---|---|---|
| url Required | string | The URL to open. |
如果系统无法打开指定 URL,此方法将执行失败。若传入非 http(s) 协议 URL,建议先调用
canOpenURL()进行检查。
对于网页 URL,必须正确设置协议(
"http://"或"https://")!
在模拟器上此方法可能表现不同,例如 iOS 模拟器无法处理
"tel:"链接(因无法访问拨号应用)。
sendIntent() Android
static sendIntent(
action: string,
extras?: Array<{key: string; value: string | number | boolean}>,
): Promise<void>;
启动带附加参数的 Android intent。
参数:
| Name | Type |
|---|---|
| action Required | string |
| extras | Array<{key: string, value: string | number | boolean}> |