前言
网上大部分的文章说的都是 Tauri V1 版本的。本文主要说一下 Tauri V2 版本的实现。
在 Tauri V2 应用中,支持通过特定的 URL 来在浏览器中打开 App 功能,可以通过设置协议和配置相应的内容来实现。接下来,就让我们一步步实现此功能。
安装插件
安装 @tauri-apps/plugin-deep-link
是为了将 Tauri 应用程序设置为 URL 的默认处理程序。
配置方式 1:修改 Cargo.toml
在 src-tauri/Cargo.toml
文件中增加:
[dependencies]
tauri-plugin-deep-link = "2.0.0"
# alternatively with Git:
tauri-plugin-deep-link = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
配置方式 2:通过 JS 安装
pnpm add @tauri-apps/plugin-deep-link
# or
npm add @tauri-apps/plugin-deep-link
# or
yarn add @tauri-apps/plugin-deep-link
# alternatively with Git:
pnpm add https://github.com/tauri-apps/tauri-plugin-deep-link#v2
# or
npm add https://github.com/tauri-apps/tauri-plugin-deep-link#v2
# or
yarn add https://github.com/tauri-apps/tauri-plugin-deep-link#v2
安装 tauri-plugin-single-instance
是为了确保 tauri 应用程序的单个实例正在运行。
配置方式:修改 Cargo.toml
在 src-tauri/Cargo.toml
文件中增加:
[dependencies]
tauri-plugin-single-instance = "2.0.0"
# alternatively with Git:
tauri-plugin-single-instance = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
设置自定义协议
Tauri 支持使用 tauri://
自定义协议来在浏览器中打开应用的内容。
在 src-tauri/tauri.conf.json
文件中增加:
"plugins": {
"features": {
"protocol": ["all"]
},
"window": {},
"websocket": {},
"shell": {},
"globalShortcut": {},
"deep-link": {
"schema": "coco",
"mobile": [
{ "host": "app.infini.cloud", "pathPrefix": ["/open"] },
{ "host": "localhost:9000" }
],
"desktop": {
"schemes": ["coco"]
}
}
}
实现自定义协议逻辑
在 src-tauri/src/lib.rs
文件中增加:
use tauri_plugin_deep_link::DeepLinkExt;
#[derive(Clone, serde::Serialize)]
struct Payload {
args: Vec<String>,
cwd: String,
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
let mut ctx = tauri::generate_context!();
tauri::Builder::default()
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_deep_link::init())
.plugin(tauri_plugin_single_instance::init(|app, argv, cwd| {
// println!("{}, {argv:?}, {cwd}", app.package_info().name);
app.emit("single-instance", Payload { args: argv, cwd })
.unwrap();
}))
.invoke_handler(tauri::generate_handler![
])
.setup(|app| {
init(app.app_handle());
#[cfg(target_os = "macos")]
app.set_activation_policy(ActivationPolicy::Accessory);
#[cfg(any(target_os = "linux", all(debug_assertions, windows)))]
app.deep_link().register_all()?;
app.deep_link().on_open_url(|event| {
dbg!(event.urls());
});
Ok(())
})
.run(ctx)
.expect("error while running tauri application");
}
权限配置
在 src-tauri/capabilities/default.json
文件中增加:
"permissions": [
"oauth:allow-start",
"deep-link:allow-get-current",
"deep-link:default",
"deep-link:allow-register",
]
MacOS 配置
在 Tauri 项目中,src-tauri/Info.plist
是一个 macOS 特有的文件,它是 macOS 应用程序的 信息属性列表。这个文件是 macOS 应用的重要组成部分,用于定义应用程序的基本属性和行为。例如,应用的名称、图标、权限、支持的 URL 协议等都可以在这里配置。
在 src-tauri/Info.plist
文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSCameraUsageDescription</key>
<string>Request camera access for WebRTC</string>
<key>NSMicrophoneUsageDescription</key>
<string>Request microphone access for WebRTC</string>
<key>CFBundleIdentifier</key>
<string>rs.coco.app</string>
<key>NSPrefPaneIconLabel</key>
<string>coco-ai</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>rs.coco.app</string>
<key>CFBundleURLSchemes</key>
<array>
<string>coco</string>
</array>
</dict>
</array>
</dict>
</plist>
前端调用
Tauri APP 代码:
import {
onOpenUrl,
getCurrent as getCurrentDeepLinkUrls,
} from "@tauri-apps/plugin-deep-link";
const handleUrl = (url: string) => {
try {
const urlObject = new URL(url);
console.error("urlObject:", urlObject);
switch (urlObject.pathname) {
case "oauth_callback":
const code = urlObject.searchParams.get("code");
const provider = urlObject.searchParams.get("provider");
// 要执行的逻辑
break;
default:
console.log("Unhandled deep link path:", urlObject.pathname);
}
setLastUrl(url);
} catch (err) {
console.error("Failed to parse URL:", err);
setError("Invalid URL format");
}
};
// Fetch the initial deep link intent
useEffect(() => {
// coco://oauth_calback?code=&provider=
// handleOAuthCallback("cu0bpu53q95r66at2010", "coco-cloud");
//
getCurrentDeepLinkUrls()
.then((urls) => {
console.log("URLs:", urls);
if (urls && urls.length > 0) {
handleUrl(urls[0]);
}
})
.catch((err) => {
console.error("Failed to get initial URLs:", err);
setError("Failed to get initial URLs");
});
const unlisten = onOpenUrl((urls) => handleUrl(urls[0]));
return () => {
unlisten.then((fn) => fn());
};
}, []);
浏览器 web 端代码
<a href="coco://oauth_callback?code=ctvracbq50ke7o4qksj0&provider=coco-cloud">
In order to continue, please click here to launch Coco AI
</a>
适用场景
- 通过 Web 页面触发桌面应用逻辑。
- 配合 OAuth 登录、支付回调等需要浏览器完成的操作。
- 跨平台数据交互。
- 在线文档与帮助中心。
- 动态加载和更新。
小结
通过以上步骤,我们实现了 Tauri 应用在浏览器中打开的功能,支持灵活配置自定义协议和多平台适配。
参考资料
开源
最近,我正在基于 Tauri 开发一款项目,名为 Coco。目前已开源,项目仍在不断完善中,欢迎大家前往支持并为项目点亮免费的 star 🌟!
作为个人的第一个 Tauri 项目,开发过程中也是边探索边学习。希望能与志同道合的朋友一起交流经验、共同成长!
代码中如有问题或不足之处,期待小伙伴们的宝贵建议和指导!
- 官网: coco.rs/
- 前端仓库: github.com/infinilabs/…
- 服务端仓库: github.com/infinilabs/…
非常感谢您的支持与关注!