移动设备上的文件关联
Tauri 支持在 Android 和 iOS 上的文件关联,允许你的应用被注册为特定文件类型的处理程序。当用户打开与你声明的关联匹配的文件时,操作系统会启动你的应用并传递文件 URL。
🌐 Tauri supports file associations on Android and iOS, allowing your app to be registered as a handler for specific file types. When a user opens a file that matches your declared associations, the operating system launches your app and delivers the file URL.
在 Android 上,文件关联是通过 intent filters 实现的,这些过滤器由 Tauri 构建系统根据你的配置自动生成。
🌐 On Android, file associations are implemented using intent filters that the Tauri build system generates automatically from your configuration.
在 iOS 上,文件关联使用 CFBundleDocumentTypes,并可选地使用 UTExportedTypeDeclarations 来支持自定义文件类型。
🌐 On iOS, file associations use CFBundleDocumentTypes and optionally UTExportedTypeDeclarations for custom file types.
🌐 Configuration
文件关联在 tauri.conf.json 的 bundle.fileAssociations 下声明。Tauri CLI 使用此配置生成适当的特定平台元数据(在 AndroidManifest.xml 中的 Android intent 过滤器,在 Info.plist 中的 iOS 文档类型)。
🌐 File associations are declared in tauri.conf.json under bundle.fileAssociations. The Tauri CLI uses this configuration to generate the appropriate platform-specific metadata (Android intent filters in AndroidManifest.xml, iOS document types in Info.plist).
数组中的每个条目表示你的应用可以处理的文件类型:
🌐 Each entry in the array represents a file type your app can handle:
{ "bundle": { "fileAssociations": [ { "ext": ["png"], "mimeType": "image/png" }, { "ext": ["jpg", "jpeg"], "mimeType": "image/jpeg" } ] }}🌐 Configuration Options
ext— 要关联的文件扩展名列表(不带前导点)。mimeType— 文件的 MIME 类型(例如image/png)。在 Android 上,意图过滤匹配时需要指定。Tauri 在未指定时会根据扩展名推断常见的 MIME 类型。role— 应用相对于文件类型的角色。在苹果平台上对应CFBundleTypeRole。值:Editor(默认),Viewer,Shell,QLGenerator,None。rank— 处理此文件类型的应用的排名。在苹果平台上对应LSHandlerRank。值:Default(默认)、Owner、Alternate、None。name— 文件类型的显示名称。默认为第一个扩展名。exportedType— 定义由你的应用拥有的自定义文件类型。在 Apple 平台上将其与非标准文件扩展名关联时是必须的。androidIntentActionFilters— 要注册的 Android 意图操作。可选值:Send、SendMultiple、View。默认情况下都会使用这三个。
🌐 Custom File Types
对于非标准文件扩展名,你应定义一个 exportedType,以便 Apple 平台可以识别文件类型。identifier 应该是一个对你的应用唯一的反向 DNS 字符串,conformsTo 列出了父类型:
🌐 For non-standard file extensions, you should define an exportedType so Apple platforms can identify the file type. The identifier should be a reverse-DNS string unique to your app, and conformsTo lists the parent types:
{ "bundle": { "fileAssociations": [ { "ext": ["mydata"], "mimeType": "application/octet-stream", "exportedType": { "identifier": "com.example.myapp.mydata", "conformsTo": ["public.data"] } } ] }}常见的 conformsTo 值包括 public.data、public.image、public.json 和 public.plain-text。
🌐 Common conformsTo values include public.data, public.image, public.json, and public.plain-text.
🌐 Handling Opened Files
当使用你的应用打开文件时,Tauri 会发出一个包含文件 URL 的 RunEvent::Opened 事件。该事件在 macOS、iOS 和 Android 上可用。
🌐 When a file is opened with your app, Tauri emits a RunEvent::Opened event containing the file URLs. This event is available on macOS, iOS, and Android.
你需要处理两种情况:
🌐 You need to handle two cases:
- 应用已在运行 — 该事件在运行时传递。
- 应用由文件打开启动——此事件在启动过程中触发,因此你应该存储这些 URL 并让它们可供前端使用。
将传入的 URL 存储在托管状态中,通过前端在启动时可以调用的命令将其暴露出来,并在 RunEvent::Opened 触发时发出 Tauri 事件,以便前端在应用已经运行时可以做出反应:
🌐 Store incoming URLs in managed state, expose them with a command the frontend can call on startup, and emit a Tauri event whenever RunEvent::Opened fires so the frontend can react while the app is already running:
use std::sync::Mutex;use tauri::Manager;
struct OpenedUrls(Mutex<Vec<tauri::Url>>);
#[tauri::command]fn opened_urls(app: tauri::AppHandle) -> Vec<tauri::Url> { app.state::<OpenedUrls>().0.lock().unwrap().clone()}
#[cfg_attr(mobile, tauri::mobile_entry_point)]pub fn run() { tauri::Builder::default() .manage(OpenedUrls(Mutex::new(vec![]))) .invoke_handler(tauri::generate_handler![opened_urls]) .build(tauri::generate_context!()) .expect("error while running tauri application") .run(|app, event| { #[cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))] if let tauri::RunEvent::Opened { urls } = event { use tauri::Emitter; app.state::<OpenedUrls>() .0 .lock() .unwrap() .extend(urls.clone()); app.emit("opened", urls).unwrap(); } });}下面的前端在两个地方连接到了那个 Rust 代码:
🌐 The frontend below is wired to that Rust code in two places:
invoke('opened_urls')调用opened_urls命令,因此网页视图可以读取在 UI 加载完成之前存储的 URL(从文件打开的冷启动)。listen('opened', …)订阅了在 Rust 中传递给app.emit("opened", urls)的相同事件名称,因此在应用已经运行时触发的文件打开事件会立即传递。
import { listen } from '@tauri-apps/api/event';import { invoke } from '@tauri-apps/api/core';
// Cold start: URLs may already be in Rust state before the frontend loadsconst initialUrls = await invoke('opened_urls');if (initialUrls.length > 0) { handleFiles(initialUrls);}
// Warm: Rust emits the "opened" event when RunEvent::Opened firesawait listen('opened', (event) => { handleFiles(event.payload);});Tauri 中文网 - 粤ICP备13048890号
Nodejs.cn 旗下网站