很多开发者在把 Tauri 2 应用上架到 iOS(真机或模拟器)时,都会在文件保存这一步踩坑:明明代码代码在其他平台没问题,在 iOS 路径就返回 null,或者在「文件」App 里根本看不到自己的 App 文件夹。
下面我把最常见的几个坑总结成一份避坑科普文,帮你一次性避开这些“iOS 特色”问题。
坑 1:@tauri-apps/plugin-dialog 的 save() 在 iOS 上经常返回 null 或路径不可用
现象:
调用 const path = await save({...}) 后,一个 0KB 的文件写入成功,但是 path 返回是 null。
避坑方法:
- 不要过度依赖
dialog.save()来实现“用户任意选择保存位置”。 - 优先使用 直接写入 App 的 Documents 目录(见坑 3)。
- capabilities 中确保开启
dialog:save权限。
坑 2:文件明明写入了,但「文件」App 里完全看不到 “Mind Elixir” 文件夹
现象:
用了 BaseDirectory.Document 保存文件后,在「文件」App → 浏览 → On My iPhone 里找不到你的 App 文件夹。
原因: iOS 沙盒机制严格控制 App 的 Documents 目录是否对「文件」App 可见。Tauri 默认生成的 iOS 项目不会自动添加暴露文件夹的配置,就算你写再多文件,文件夹也不会出现。
避坑方法(最关键的一步):
在 Info.plist 中添加以下两个 key(必须同时添加):
<key>UIFileSharingEnabled</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
位置:通常在 src-tauri/gen/apple/ios/App/App/Info.plist(或你的项目对应路径),加在 <dict> 标签内,</dict> 之前。
添加后必须重新构建并安装 App(cargo tauri ios build 或用 Xcode 编译),然后:
- 先执行一次写入操作(创建文件)。
- 完全退出「文件」App(上滑关闭),重新打开并下拉刷新「On My iPhone」。
此时你应该能看到和 App 同名的文件夹(显示名称来自 productName 或 Xcode Display Name)。
注意:这两个 key 只控制可见性,不影响代码读写。
坑 3:iOS 上最好的保存方式其实不是 dialog,而是直接用 Documents 目录
推荐做法:
import { writeTextFile, BaseDirectory } from '@tauri-apps/plugin-fs'
await writeTextFile('my-note.md', '你的内容...', {
dir: BaseDirectory.Document
})
优点:
- 最稳定,几乎不会出现 0 字节文件的问题。
- 用户可以在「文件」App 里直接看到和管理文件(添加上面两个 plist key 后)。
- 无需处理复杂的 URI 和潜在的 fs bug。
如果你想让用户输入文件名,可以结合 prompt 或自定义输入框实现。
总结建议
在 Tauri 2 + iOS 开发中:
- 优先使用
BaseDirectory.Document直接保存(最稳)。 - 必须在 Info.plist 添加
UIFileSharingEnabled和LSSupportsOpeningDocumentsInPlace。 - 谨慎使用
dialog.save()+writeFile,因为移动端兼容性还有待完善(官方 issue 仍在跟进)。 - 开发时多用控制台日志 + Safari/XCode 调试,遇到路径问题先检查 plist 和权限。
避开这几个坑后,你的 Mind Elixir(或其他 App)在 iOS 上的文件保存功能就会顺畅很多。iOS 的沙盒和文件系统规则和桌面差异很大,提前了解这些“Apple 特色”能省下大量调试时间。
(本文基于 Tauri 2 常见 issue 和实际开发经验总结,iOS 规则可能随系统版本微调,建议以 Apple 官方文档为准。)