Linking
Linking
为你提供了一个通用接口,用于与传入和传出的应用链接进行交互。
每个链接 (URL) 都有一个 URL 方案,一些网站以 https://
或 http://
为前缀,而 http
是 URL 方案。为了简洁起见,我们称之为 scheme。
除了 https
之外,你可能也很熟悉 mailto
方案。当你打开一个使用 mailto 方案的链接时,你的操作系统将打开一个已安装的邮件应用程序。类似地,还有用于拨打电话和发送 SMS 的方案。请阅读以下关于 内置 URL 方案的更多信息。
与使用 mailto 方案类似,可以通过使用自定义 URL 方案链接到其他应用程序。例如,当你收到来自 Slack 的 魔法链接 电子邮件时,启动 Slack 按钮是一个锚标记,其 href 看起来像这样:slack://secret/magic-login/other-secret
。与 Slack 类似,你可以告诉操作系统你想要处理自定义方案。当 Slack 应用打开时,它会收到用于打开它的 URL。这通常被称为深度链接。请阅读以下关于如何获取进入你的应用的深度链接的更多信息。
自定义 URL 方案不是在移动设备上打开你的应用程序的唯一方法。例如,如果你想通过电子邮件向某人发送一个链接以便在移动设备上打开,则使用自定义 URL 方案并不理想,因为用户可能会在桌面设备上打开电子邮件,这样链接将无法工作。相反,你应该使用标准的 https
链接,例如 https://www.myapp.io/records/1234546
。在移动设备上,可以将这些链接配置为打开你的应用。在 Android 上,此功能称为 深度链接,而在 iOS 上,它被称为 通用链接。
内置 URL 方案
正如引言中提到的,在每个平台上都存在一些用于核心功能的 URL 方案。以下是一个非详尽的列表,但涵盖了最常用的方案。
方案 | 描述 | iOS | Android |
---|---|---|---|
mailto | 打开邮件应用,例如:mailto: support@expo.io | ✅ | ✅ |
tel | 打开电话应用,例如:tel:+123456789 | ✅ | ✅ |
sms | 打开短信应用,例如:sms:+123456789 | ✅ | ✅ |
https / http | 打开 Web 浏览器应用,例如:https://expo.io | ✅ | ✅ |
启用深度链接
如果你想在你的应用中启用深度链接,请阅读以下指南
- Android
- iOS
有关如何在 Android 上添加对深度链接支持的说明,请参阅 启用应用内容的深度链接 - 为你的深度链接添加 Intent 过滤器。
如果你希望在 MainActivity 的现有实例中接收 intent,你可以将 AndroidManifest.xml
中 MainActivity 的 launchMode
设置为 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];
}
如果你的应用正在使用 通用链接,你还需要添加以下代码
- (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,则 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
键中添加特定方案(见下文),则 promise 将拒绝。
参数
名称 | 类型 | 描述 |
---|---|---|
url 必需 | string | 要打开的 URL。 |
对于 Web 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
中指定你要处理的方案的 intent。可以在 此处 找到常见 intent 的列表。例如,要处理
https
方案,需要将以下内容添加到你的 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.cn/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 必需 | string | 要打开的 URL。 |
如果系统不知道如何打开指定的 URL,则此方法将失败。如果你传入非 http(s) URL,最好先检查
canOpenURL()
。
对于 Web URL,必须相应地设置协议 (
"http://"
,"https://"
)!
此方法在模拟器中的行为可能有所不同,例如,由于无法访问拨号器应用,因此无法在 iOS 模拟器中处理
"tel:"
链接。
sendIntent()
Android
static sendIntent(
action: string,
extras?: Array<{key: string; value: string | number | boolean}>,
): Promise<void>;
启动带有 extras 的 Android intent。
参数
名称 | 类型 |
---|---|
action 必需 | string |
extras | Array<{key: string, value: string | number | boolean}> |