Rust跨平台应用Tauri插件tauri-plugin-deep-link的使用,实现深度链接处理与自定义URL协议支持
将您的Tauri应用程序设置为URL的默认处理程序。
平台 | 支持 |
---|---|
Linux | ✓ |
Windows | ✓ |
macOS | ✓ |
Android | ✓ |
iOS | ✓ |
安装
此插件需要至少Rust版本1.77.2
我们推荐三种通用的安装方法。
- 使用crates.io和npm(最简单,需要您信任我们的发布管道正常工作)
- 使用git标签/修订哈希直接从Github拉取源代码(最安全)
- 在您的Tauri项目中使用git子模块安装此仓库,然后使用文件协议引入源代码(最安全,但使用不便)
通过将以下内容添加到您的Cargo.toml
文件来安装核心插件:
src-tauri/Cargo.toml
[dependencies]
tauri-plugin-deep-link = "2.0.0"
# 或者使用Git:
tauri-plugin-deep-link = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
您可以使用您喜欢的JavaScript包管理器安装JavaScript Guest绑定:
pnpm add @tauri-apps/plugin-deep-link
# 或者
npm add @tauri-apps/plugin-deep-link
# 或者
yarn add @tauri-apps/plugin-deep-link
设置
Android
对于应用链接,您需要一个具有.well-known/assetlinks.json
端点的服务器,该端点必须以给定格式返回文本响应:
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "$APP_BUNDLE_ID",
"sha256_cert_fingerprints": [
$CERT_FINGERPRINT
]
}
}
]
其中$APP_BUNDLE_ID
是在tauri.conf.json > identifier
中定义的值,将-
替换为_
,$CERT_FINGERPRINT
是您的应用签名证书的SHA256指纹列表。
iOS
对于通用链接,您需要一个具有.well-known/apple-app-site-association
端点的服务器,该端点必须以给定格式返回文本响应:
{
"applinks": {
"details": [
{
"appIDs": [ "$DEVELOPMENT_TEAM_ID.$APP_BUNDLE_ID" ],
"components": [
{
"/": "/open/*",
"comment": "匹配任何路径以/open/开头的URL"
}
]
}
]
}
}
其中$DEVELOPMENT_TEAM_ID
是在tauri.conf.json > bundle > iOS > developmentTeam
中定义的值或APPLE_DEVELOPMENT_TEAM
环境变量,$APP_BUNDLE_ID
是在tauri.conf.json > identifier
中定义的值。
要验证您的域是否已正确配置以公开应用关联,您可以运行以下命令:
curl -v https://app-site-association.cdn-apple.com/a/v1/<host>
apple-app-site-association文件必须通过HTTPS提供,并且响应必须包含Content-Type: application/json
头。
要在iOS模拟器上快速打开应用链接,您可以执行xcrun simctl openurl booted <url>
。
配置
在tauri.conf.json > plugins > deep-link
下,配置您想要与您的应用程序关联的域(移动端)和方案(桌面端):
{
"plugins": {
"deep-link": {
"mobile": [
{ "host": "your.website.com", "pathPrefix": ["/open"] },
{ "host": "another.site.br" }
],
"desktop": {
"schemes": ["something", "my-tauri-app"]
}
}
}
}
用法
首先,您需要向Tauri注册核心插件:
src-tauri/src/lib.rs
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_deep_link::init()) // 注册深度链接插件
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
之后,所有插件的API都可通过JavaScript Guest绑定使用:
import { onOpenUrl } from '@tauri-apps/plugin-deep-link'
await onOpenUrl((urls) => {
console.log('deep link:', urls) // 处理深度链接URL
})
请注意,插件仅在macOS、iOS和Android上发出事件。在Windows和Linux上,操作系统将使用URL作为CLI参数生成一个新的应用程序实例。如果您希望您的应用程序在Windows和Linux上的行为与其他平台类似,您可以使用single-instance插件,并启用deep-link
功能。
贡献
接受PR。请在提交拉取请求之前确保阅读贡献指南。
贡献者
合作伙伴
有关完整的赞助商列表,请访问我们的网站和Open Collective。
许可证
代码:© 2015 - 现在 - The Commons Conservancy内的Tauri计划。
MIT或MIT/Apache 2.0(如果适用)。
完整示例代码
// src-tauri/src/main.rs
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_deep_link::init()) // 初始化深度链接插件
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
// 前端JavaScript代码
import { onOpenUrl } from '@tauri-apps/plugin-deep-link'
// 监听深度链接事件
await onOpenUrl((urls) => {
console.log('Received deep link URLs:', urls)
// 在这里处理深度链接逻辑
// 例如:解析URL参数、导航到特定页面等
})
// tauri.conf.json 配置示例
{
"plugins": {
"deep-link": {
"mobile": [
{ "host": "myapp.com", "pathPrefix": ["/open"] }
],
"desktop": {
"schemes": ["my-tauri-app"]
}
}
}
}
基于上述内容,以下是完整的示例demo:
// src-tauri/Cargo.toml
[package]
name = "tauri-deep-link-demo"
version = "0.1.0"
description = "Tauri deep link plugin demo"
authors = ["Your Name"]
license = "MIT"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tauri = { version = "1.0", features = ["api-all"] }
tauri-plugin-deep-link = "2.0.0" // 深度链接插件
[build-dependencies]
tauri-build = { version = "1.0" }
// src-tauri/src/main.rs
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_deep_link::init()) // 初始化深度链接插件
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
// src-tauri/tauri.conf.json
{
"build": {
"beforeDevCommand": "",
"beforeBuildCommand": "",
"devPath": "../dist",
"distDir": "../dist"
},
"package": {
"productName": "DeepLinkDemo",
"version": "0.1.0"
},
"tauri": {
"allowlist": {
"all": false,
"shell": {
"all": false,
"open": true
}
},
"bundle": {
"active": true,
"targets": "all",
"identifier": "com.example.tauri-deep-link-demo",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
},
"security": {
"csp": null
},
"windows": [
{
"fullscreen": false,
"resizable": true,
"title": "DeepLinkDemo",
"width": 800,
"height": 600
}
],
"plugins": {
"deep-link": {
"mobile": [
{ "host": "myapp.com", "pathPrefix": ["/open"] }
],
"desktop": {
"schemes": ["my-tauri-app"]
}
}
}
}
}
// 前端代码 src/main.js
import { onOpenUrl } from '@tauri-apps/plugin-deep-link'
// 监听深度链接事件
async function setupDeepLinkListener() {
try {
await onOpenUrl((urls) => {
console.log('Received deep link URLs:', urls)
// 处理深度链接逻辑
urls.forEach(url => {
console.log('Processing URL:', url)
// 解析URL参数
const urlObj = new URL(url)
const params = new URLSearchParams(urlObj.search)
// 根据URL路径和参数执行相应操作
if (urlObj.pathname.includes('/open')) {
const action = params.get('action')
const id = params.get('id')
console.log('Action:', action)
console.log('ID:', id)
// 导航到特定页面或执行特定操作
handleDeepLinkAction(action, id)
}
})
})
console.log('Deep link listener registered successfully')
} catch (error) {
console.error('Failed to register deep link listener:', error)
}
}
function handleDeepLinkAction(action, id) {
// 根据action和id执行相应的业务逻辑
switch (action) {
case 'view':
console.log('Opening view for ID:', id)
// 打开查看页面
break
case 'edit':
console.log('Opening edit for ID:', id)
// 打开编辑页面
break
default:
console.log('Unknown action:', action)
}
}
// 初始化应用
document.addEventListener('DOMContentLoaded', () => {
console.log('App initialized')
setupDeepLinkListener()
})
// package.json
{
"name": "tauri-deep-link-demo",
"version": "0.1.0",
"description": "Tauri deep link plugin demo",
"main": "src/main.js",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"tauri": "tauri"
},
"dependencies": {
"@tauri-apps/api": "^1.0.0",
"@tauri-apps/plugin-deep-link": "^2.0.0"
},
"devDependencies": {
"@tauri-apps/cli": "^1.0.0",
"vite": "^3.0.0"
}
}
Tauri插件tauri-plugin-deep-link使用指南
插件概述
tauri-plugin-deep-link是一个用于Tauri应用程序的插件,支持深度链接处理和自定义URL协议注册。它允许您的应用响应系统级的URL调用,实现从外部应用或浏览器直接打开您的Tauri应用特定功能。
主要功能
- 注册自定义URL协议(如:
myapp://
) - 处理深度链接调用
- 跨平台支持(Windows、macOS、Linux)
- 监听URL打开事件
安装方法
1. 添加依赖
在Cargo.toml
中添加:
[dependencies]
tauri-plugin-deep-link = "0.1"
serde = { version = "1.0", features = ["derive"] }
2. 注册插件
在src/main.rs
中:
use tauri_plugin_deep_link;
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_deep_link::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
基本使用方法
1. 注册自定义协议
use tauri::Manager;
use tauri_plugin_deep_link::DeepLinkExt;
#[tauri::command]
async fn register_protocol(app_handle: tauri::AppHandle) -> Result<(), String> {
app_handle.deep_link().register("myapp").map_err(|e| e.to_string())
}
2. 监听深度链接事件
use tauri::{Manager, Window};
use tauri_plugin_deep_link::DeepLinkExt;
fn setup_deep_link_listener(app: &tauri::App) -> Result<(), Box<dyn std::error::Error>> {
let app_handle = app.handle();
let window = app.get_window("main").unwrap();
app_handle.deep_link()
.on_open(move |url| {
println!("Received deep link: {}", url);
// 处理URL逻辑
handle_deep_link(url, &window);
});
Ok(())
}
fn handle_deep_link(url: String, window: &Window) {
// 解析URL并执行相应操作
if url.starts_with("myapp://open/") {
let path = url.replace("myapp://open/", "");
window.eval(&format!("window.location.hash = '#/{}'", path)).unwrap();
}
}
3. 完整示例
use tauri::{Manager, Window};
use tauri_plugin_deep_link::DeepLinkExt;
#[tauri::command]
async fn init_deep_link(app_handle: tauri::AppHandle, window: Window) -> Result<(), String> {
// 注册协议
app_handle.deep_link()
.register("myapp")
.map_err(|e| e.to_string())?;
// 设置监听器
let window_clone = window.clone();
app_handle.deep_link()
.on_open(move |url| {
println!("Deep link received: {}", url);
if let Some(query) = url.strip_prefix("myapp://") {
match query {
"home" => {
window_clone.eval("window.location.hash = '#/home'").unwrap();
}
"settings" => {
window_clone.eval("window.location.hash = '#/settings'").unwrap();
}
_ if query.starts_with("product/") => {
let product_id = query.replace("product/", "");
window_clone.eval(&format!(
"window.location.hash = '#/product/{}'",
product_id
)).unwrap();
}
_ => {}
}
}
});
Ok(())
}
平台特定配置
macOS配置
在tauri.conf.json
中添加:
{
"tauri": {
"bundle": {
"macOS": {
"category": "public.app-category.productivity"
}
}
}
}
Windows配置
在tauri.conf.json
中添加协议注册:
{
"tauri": {
"bundle": {
"windows": {
"protocols": [
{
"name": "MyApp",
"schemes": ["myapp"]
}
]
}
}
}
}
错误处理
use tauri_plugin_deep_link::DeepLinkError;
fn handle_deep_link_errors() -> Result<(), DeepLinkError> {
// 错误处理示例
match app_handle.deep_link().register("myapp") {
Ok(_) => println!("Protocol registered successfully"),
Err(DeepLinkError::ProtocolAlreadyRegistered) => {
eprintln!("Protocol is already registered");
}
Err(e) => return Err(e),
}
Ok(())
}
注意事项
- 在macOS上,需要在应用首次运行时请求权限
- Windows需要管理员权限才能注册协议
- 协议名称应该保持唯一性,避免与其他应用冲突
- 处理完深度链接后应该及时释放资源
这个插件为Tauri应用提供了完整的深度链接解决方案,让您的应用能够更好地与其他应用和系统集成。
完整示例demo
以下是一个完整的Tauri应用示例,展示了如何使用tauri-plugin-deep-link插件:
// src/main.rs
use tauri::{Manager, Window};
use tauri_plugin_deep_link::DeepLinkExt;
// 前端命令:初始化深度链接
#[tauri::command]
async fn init_deep_link(app_handle: tauri::AppHandle, window: Window) -> Result<(), String> {
// 注册自定义协议
app_handle.deep_link()
.register("myapp")
.map_err(|e| e.to_string())?;
// 克隆窗口用于闭包
let window_clone = window.clone();
// 设置深度链接监听器
app_handle.deep_link()
.on_open(move |url| {
println!("接收到深度链接: {}", url);
// 解析URL并执行相应操作
if let Some(query) = url.strip_prefix("myapp://") {
match query {
"home" => {
// 导航到首页
window_clone.eval("window.location.hash = '#/home'").unwrap();
}
"settings" => {
// 导航到设置页
window_clone.eval("window.location.hash = '#/settings'").unwrap();
}
_ if query.starts_with("product/") => {
// 导航到产品详情页
let product_id = query.replace("product/", "");
window_clone.eval(&format!(
"window.location.hash = '#/product/{}'",
product_id
)).unwrap();
}
_ => {
// 处理未知链接
println!("未知的深度链接: {}", url);
}
}
}
});
Ok(())
}
fn main() {
tauri::Builder::default()
// 注册深度链接插件
.plugin(tauri_plugin_deep_link::init())
// 注册前端命令
.invoke_handler(tauri::generate_handler![init_deep_link])
.setup(|app| {
// 获取主窗口
let window = app.get_window("main").unwrap();
// 初始化深度链接
let app_handle = app.handle();
app_handle.deep_link()
.register("myapp")
.expect("无法注册协议");
// 设置深度链接监听器
let window_clone = window.clone();
app_handle.deep_link()
.on_open(move |url| {
println!("应用启动时接收到深度链接: {}", url);
handle_deep_link(url, &window_clone);
});
Ok(())
})
.run(tauri::generate_context!())
.expect("运行Tauri应用时出错");
}
// 处理深度链接的辅助函数
fn handle_deep_link(url: String, window: &Window) {
if let Some(query) = url.strip_prefix("myapp://") {
match query {
"home" => {
window.eval("window.location.hash = '#/home'").unwrap();
}
"settings" => {
window.eval("window.location.hash = '#/settings'").unwrap();
}
_ if query.starts_with("open/") => {
let path = query.replace("open/", "");
window.eval(&format!("window.location.hash = '#/{}'", path)).unwrap();
}
_ => {
println!("未处理的深度链接: {}", url);
}
}
}
}
# Cargo.toml
[package]
name = "my-tauri-app"
version = "0.1.0"
description = "A Tauri app with deep link support"
authors = ["Your Name"]
license = "MIT"
edition = "2021"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tauri = { version = "1.0", features = ["api-all"] }
tauri-plugin-deep-link = "0.1"
[build-dependencies]
tauri-build = { version = "1.0" }
// tauri.conf.json
{
"build": {
"beforeBuildCommand": "",
"beforeDevCommand": "",
"devPath": "../dist",
"distDir": "../dist"
},
"package": {
"productName": "My Tauri App",
"version": "0.1.0"
},
"tauri": {
"allowlist": {
"all": false,
"deep-link": {
"all": true,
"register": true,
"unregister": true,
"on-open": true
}
},
"bundle": {
"active": true,
"category": "DeveloperTool",
"copyright": "",
"deb": {
"depends": []
},
"externalBin": [],
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"identifier": "com.example.my-tauri-app",
"macOS": {
"category": "public.app-category.productivity"
},
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": "",
"protocols": [
{
"name": "MyApp",
"schemes": ["myapp"]
}
]
}
},
"security": {
"csp": null
},
"updater": {
"active": false
},
"windows": [
{
"fullscreen": false,
"height": 600,
"resizable": true,
"title": "My Tauri App",
"width": 800
}
]
}
}
这个完整示例展示了如何在Tauri应用中集成深度链接功能,包括协议注册、链接监听和相应的页面导航处理。