distributing-tauri-for-macos
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTauri macOS Distribution
Tauri macOS 应用分发
This skill covers distributing Tauri v2 applications on macOS, including DMG installers and application bundle configuration.
本指南涵盖在macOS上分发Tauri v2应用的相关内容,包括DMG安装程序和应用包配置。
Overview
概述
macOS distribution for Tauri apps involves two primary formats:
- Application Bundle (.app) - The executable directory containing all app components
- DMG Installer (.dmg) - A disk image that wraps the app bundle for easy drag-and-drop installation
Tauri应用的macOS分发主要涉及两种格式:
- 应用包(.app) - 包含所有应用组件的可执行目录
- DMG安装程序(.dmg) - 一种磁盘镜像文件,包裹应用包以支持拖放式安装
Building for macOS
为macOS构建应用
Build Commands
构建命令
Generate specific bundle types using the Tauri CLI:
bash
undefined使用Tauri CLI生成特定类型的安装包:
bash
undefinedBuild app bundle only
仅构建应用包
npm run tauri build -- --bundles app
yarn tauri build --bundles app
pnpm tauri build --bundles app
cargo tauri build --bundles app
npm run tauri build -- --bundles app
yarn tauri build --bundles app
pnpm tauri build --bundles app
cargo tauri build --bundles app
Build DMG installer only
仅构建DMG安装程序
npm run tauri build -- --bundles dmg
yarn tauri build --bundles dmg
pnpm tauri build --bundles dmg
cargo tauri build --bundles dmg
npm run tauri build -- --bundles dmg
yarn tauri build --bundles dmg
pnpm tauri build --bundles dmg
cargo tauri build --bundles dmg
Build both
同时构建两者
npm run tauri build -- --bundles app,dmg
undefinednpm run tauri build -- --bundles app,dmg
undefinedApplication Bundle Structure
应用包结构
The directory follows macOS conventions:
.app<productName>.app/
Contents/
Info.plist # App metadata and configuration
MacOS/
<app-name> # Main executable
Resources/
icon.icns # App icon
[bundled resources] # Additional resources
_CodeSignature/ # Code signature files
Frameworks/ # Bundled frameworks
PlugIns/ # App plugins
SharedSupport/ # Support files.app目录遵循macOS规范:
<productName>.app/
Contents/
Info.plist # 应用元数据和配置
MacOS/
<app-name> # 主可执行文件
Resources/
icon.icns # 应用图标
[bundled resources] # 附加资源
_CodeSignature/ # 代码签名文件
Frameworks/ # 捆绑的框架
PlugIns/ # 应用插件
SharedSupport/ # 支持文件DMG Installer Configuration
DMG安装程序配置
Configure DMG appearance in :
tauri.conf.json在中配置DMG的外观:
tauri.conf.jsonComplete DMG Configuration Example
完整DMG配置示例
json
{
"bundle": {
"macOS": {
"dmg": {
"background": "./images/dmg-background.png",
"windowSize": {
"width": 660,
"height": 400
},
"windowPosition": {
"x": 400,
"y": 400
},
"appPosition": {
"x": 180,
"y": 220
},
"applicationFolderPosition": {
"x": 480,
"y": 220
}
}
}
}
}json
{
"bundle": {
"macOS": {
"dmg": {
"background": "./images/dmg-background.png",
"windowSize": {
"width": 660,
"height": 400
},
"windowPosition": {
"x": 400,
"y": 400
},
"appPosition": {
"x": 180,
"y": 220
},
"applicationFolderPosition": {
"x": 480,
"y": 220
}
}
}
}
}DMG Configuration Options
DMG配置选项
| Option | Type | Default | Description |
|---|---|---|---|
| string | - | Path to background image relative to |
| number | 660 | DMG window width in pixels |
| number | 400 | DMG window height in pixels |
| number | - | Initial window X position on screen |
| number | - | Initial window Y position on screen |
| number | 180 | App icon X position in window |
| number | 220 | App icon Y position in window |
| number | 480 | Applications folder X position |
| number | 480 | Applications folder Y position |
Note: Icon sizes and positions may not apply correctly when building on CI/CD platforms due to a known issue with headless environments.
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| string | - | 相对于src-tauri的背景图片路径 |
| number | 660 | DMG窗口宽度(像素) |
| number | 400 | DMG窗口高度(像素) |
| number | - | 窗口在屏幕上的初始X坐标 |
| number | - | 窗口在屏幕上的初始Y坐标 |
| number | 180 | 应用图标在窗口中的X坐标 |
| number | 220 | 应用图标在窗口中的Y坐标 |
| number | 480 | 应用程序文件夹的X坐标 |
| number | 480 | 应用程序文件夹的Y坐标 |
注意: 在CI/CD平台上构建时,图标尺寸和位置可能无法正确应用,这是无头环境的已知问题。
Info.plist Customization
Info.plist自定义
Creating a Custom Info.plist
创建自定义Info.plist
Create to extend the default configuration. The Tauri CLI automatically merges this with generated values.
src-tauri/Info.plistxml
<?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>
<!-- Privacy Usage Descriptions -->
<key>NSCameraUsageDescription</key>
<string>This app requires camera access for video calls</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app requires microphone access for audio recording</string>
<key>NSLocationUsageDescription</key>
<string>This app requires location access for mapping features</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires photo library access to import images</string>
<!-- Document Types -->
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>My Document</string>
<key>CFBundleTypeExtensions</key>
<array>
<string>mydoc</string>
</array>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
</array>
<!-- URL Schemes -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.example.myapp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
</dict>
</plist>创建以扩展默认配置。Tauri CLI会自动将其与生成的值合并。
src-tauri/Info.plistxml
<?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>
<!-- Privacy Usage Descriptions -->
<key>NSCameraUsageDescription</key>
<string>This app requires camera access for video calls</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app requires microphone access for audio recording</string>
<key>NSLocationUsageDescription</key>
<string>This app requires location access for mapping features</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires photo library access to import images</string>
<!-- Document Types -->
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>My Document</string>
<key>CFBundleTypeExtensions</key>
<array>
<string>mydoc</string>
</array>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
</array>
<!-- URL Schemes -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.example.myapp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
</dict>
</plist>Common Info.plist Keys
常见Info.plist键
| Key | Description |
|---|---|
| Camera access explanation |
| Microphone access explanation |
| Location access explanation |
| Photo library access explanation |
| AppleScript/automation access |
| Supported document types |
| Custom URL schemes |
| Minimum macOS version (prefer tauri.conf.json) |
| 键 | 说明 |
|---|---|
| 相机权限说明 |
| 麦克风权限说明 |
| 位置权限说明 |
| 照片库权限说明 |
| AppleScript/自动化权限 |
| 支持的文档类型 |
| 自定义URL协议 |
| 最低支持macOS版本(推荐在tauri.conf.json中设置) |
Info.plist Localization
Info.plist本地化
Support multiple languages with localized strings:
Directory structure:
src-tauri/
infoplist/
en.lproj/
InfoPlist.strings
de.lproj/
InfoPlist.strings
fr.lproj/
InfoPlist.strings
es.lproj/
InfoPlist.stringsExample (German):
InfoPlist.strings"NSCameraUsageDescription" = "Diese App benötigt Kamerazugriff für Videoanrufe";
"NSMicrophoneUsageDescription" = "Diese App benötigt Mikrofonzugriff für Audioaufnahmen";Configure in :
tauri.conf.jsonjson
{
"bundle": {
"resources": {
"infoplist/**": "./"
}
}
}通过本地化字符串支持多语言:
目录结构:
src-tauri/
infoplist/
en.lproj/
InfoPlist.strings
de.lproj/
InfoPlist.strings
fr.lproj/
InfoPlist.strings
es.lproj/
InfoPlist.strings示例(德语):
InfoPlist.strings"NSCameraUsageDescription" = "Diese App benötigt Kamerazugriff für Videoanrufe";
"NSMicrophoneUsageDescription" = "Diese App benötigt Mikrofonzugriff für Audioaufnahmen";在中配置:
tauri.conf.jsonjson
{
"bundle": {
"resources": {
"infoplist/**": "./"
}
}
}Entitlements Configuration
权限配置(Entitlements)
Entitlements grant special capabilities when your app is code-signed.
权限(Entitlements)在应用进行代码签名时授予特殊功能。
Creating Entitlements.plist
创建Entitlements.plist
Create :
src-tauri/Entitlements.plistxml
<?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>
<!-- App Sandbox (required for App Store) -->
<key>com.apple.security.app-sandbox</key>
<true/>
<!-- Network Access -->
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<!-- File Access -->
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<!-- Hardware Access -->
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.microphone</key>
<true/>
<!-- Hardened Runtime -->
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
</dict>
</plist>创建:
src-tauri/Entitlements.plistxml
<?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>
<!-- App Sandbox (required for App Store) -->
<key>com.apple.security.app-sandbox</key>
<true/>
<!-- Network Access -->
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<!-- File Access -->
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<!-- Hardware Access -->
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.microphone</key>
<true/>
<!-- Hardened Runtime -->
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
</dict>
</plist>Configure Entitlements in tauri.conf.json
在tauri.conf.json中配置权限
json
{
"bundle": {
"macOS": {
"entitlements": "./Entitlements.plist"
}
}
}json
{
"bundle": {
"macOS": {
"entitlements": "./Entitlements.plist"
}
}
}Common Entitlements Reference
常见权限参考
Sandbox Entitlements:
| Entitlement | Description |
|---|---|
| Enable app sandbox (required for App Store) |
| Outbound network connections |
| Incoming network connections |
| Access user-selected files |
| Access Downloads folder |
Hardware Entitlements:
| Entitlement | Description |
|---|---|
| Camera access |
| Microphone access |
| USB device access |
| Bluetooth access |
Hardened Runtime Entitlements:
| Entitlement | Description |
|---|---|
| Allow JIT compilation |
| Allow unsigned executable memory |
| Load arbitrary plugins |
沙箱权限:
| 权限 | 说明 |
|---|---|
| 启用应用沙箱(App Store必填) |
| 允许出站网络连接 |
| 允许入站网络连接 |
| 允许访问用户选择的文件 |
| 允许访问下载文件夹 |
硬件权限:
| 权限 | 说明 |
|---|---|
| 相机访问权限 |
| 麦克风访问权限 |
| USB设备访问权限 |
| 蓝牙访问权限 |
强化运行时权限:
| 权限 | 说明 |
|---|---|
| 允许JIT编译 |
| 允许未签名的可执行内存 |
| 允许加载任意插件 |
macOS Bundle Configuration
macOS应用包配置
Complete macOS Configuration Example
完整macOS配置示例
json
{
"bundle": {
"icon": ["icons/icon.icns"],
"macOS": {
"minimumSystemVersion": "10.13",
"entitlements": "./Entitlements.plist",
"frameworks": [
"CoreAudio",
"./libs/libcustom.dylib",
"./frameworks/CustomFramework.framework"
],
"files": {
"embedded.provisionprofile": "./profiles/distribution.provisionprofile",
"SharedSupport/README.md": "./docs/README.md"
},
"dmg": {
"background": "./images/dmg-background.png",
"windowSize": {
"width": 660,
"height": 400
},
"appPosition": {
"x": 180,
"y": 220
},
"applicationFolderPosition": {
"x": 480,
"y": 220
}
}
}
}
}json
{
"bundle": {
"icon": ["icons/icon.icns"],
"macOS": {
"minimumSystemVersion": "10.13",
"entitlements": "./Entitlements.plist",
"frameworks": [
"CoreAudio",
"./libs/libcustom.dylib",
"./frameworks/CustomFramework.framework"
],
"files": {
"embedded.provisionprofile": "./profiles/distribution.provisionprofile",
"SharedSupport/README.md": "./docs/README.md"
},
"dmg": {
"background": "./images/dmg-background.png",
"windowSize": {
"width": 660,
"height": 400
},
"appPosition": {
"x": 180,
"y": 220
},
"applicationFolderPosition": {
"x": 480,
"y": 220
}
}
}
}
}Minimum System Version
最低系统版本
Set the minimum supported macOS version:
json
{
"bundle": {
"macOS": {
"minimumSystemVersion": "12.0"
}
}
}Default: macOS 10.13 (High Sierra)
设置最低支持的macOS版本:
json
{
"bundle": {
"macOS": {
"minimumSystemVersion": "12.0"
}
}
}默认值:macOS 10.13(High Sierra)
Including Frameworks and Libraries
包含框架和库
Bundle system frameworks or custom dylib files:
json
{
"bundle": {
"macOS": {
"frameworks": [
"CoreAudio",
"AVFoundation",
"./libs/libmsodbcsql.18.dylib",
"./frameworks/Sparkle.framework"
]
}
}
}- System frameworks: Specify name only (e.g., )
"CoreAudio" - Custom frameworks/dylibs: Provide path relative to
src-tauri
捆绑系统框架或自定义dylib文件:
json
{
"bundle": {
"macOS": {
"frameworks": [
"CoreAudio",
"AVFoundation",
"./libs/libmsodbcsql.18.dylib",
"./frameworks/Sparkle.framework"
]
}
}
}- 系统框架: 仅需指定名称(例如)
"CoreAudio" - 自定义框架/dylib: 提供相对于src-tauri的路径
Adding Custom Files to Bundle
向应用包添加自定义文件
Include additional files in the bundle's Contents directory:
json
{
"bundle": {
"macOS": {
"files": {
"embedded.provisionprofile": "./profile.provisionprofile",
"SharedSupport/docs/guide.pdf": "./assets/guide.pdf",
"Resources/config.json": "./config/default.json"
}
}
}
}Format: where paths are relative to
"destination": "source"tauri.conf.json在应用包的Contents目录中包含附加文件:
json
{
"bundle": {
"macOS": {
"files": {
"embedded.provisionprofile": "./profile.provisionprofile",
"SharedSupport/docs/guide.pdf": "./assets/guide.pdf",
"Resources/config.json": "./config/default.json"
}
}
}
}格式:,其中路径相对于tauri.conf.json
"目标路径": "源路径"Troubleshooting
故障排除
Common Issues
常见问题
DMG icons not positioned correctly on CI/CD:
- This is a known issue with headless environments
- Consider building DMGs locally or accepting default positioning
App rejected due to missing usage descriptions:
- Add all required keys to
NS*UsageDescriptionInfo.plist - Ensure descriptions clearly explain why access is needed
Entitlements not applied:
- Verify the entitlements file path in
tauri.conf.json - Ensure the app is properly code-signed
Framework not found at runtime:
- Check framework path is correct relative to
src-tauri - Verify framework is properly signed
CI/CD上DMG图标位置不正确:
- 这是无头环境的已知问题
- 考虑在本地构建DMG,或接受默认位置
应用因缺少权限说明被拒绝:
- 在中添加所有必需的
Info.plist键NS*UsageDescription - 确保说明清晰解释需要权限的原因
权限未生效:
- 验证tauri.conf.json中的权限文件路径
- 确保应用已正确签名
运行时找不到框架:
- 检查框架路径相对于src-tauri是否正确
- 验证框架已正确签名
Verification Commands
验证命令
bash
undefinedbash
undefinedCheck Info.plist contents
查看Info.plist内容
plutil -p path/to/App.app/Contents/Info.plist
plutil -p path/to/App.app/Contents/Info.plist
Verify entitlements
验证权限
codesign -d --entitlements - path/to/App.app
codesign -d --entitlements - path/to/App.app
Check code signature
检查代码签名
codesign -vvv --deep --strict path/to/App.app
codesign -vvv --deep --strict path/to/App.app
View bundle structure
查看应用包结构
find path/to/App.app -type f | head -50
undefinedfind path/to/App.app -type f | head -50
undefinedQuick Reference
快速参考
File Locations
文件位置
| File | Location | Purpose |
|---|---|---|
| | App metadata extensions |
| | Capability entitlements |
| Any path in project | DMG window background |
| | Localized Info.plist values |
| 文件 | 位置 | 用途 |
|---|---|---|
| | 应用元数据扩展 |
| | 功能权限配置 |
| 项目中的任意路径 | DMG窗口背景 |
| | 本地化Info.plist值 |
Build Output Locations
构建输出位置
src-tauri/target/release/bundle/
macos/
<ProductName>.app # Application bundle
dmg/
<ProductName>_<version>_<arch>.dmg # DMG installersrc-tauri/target/release/bundle/
macos/
<ProductName>.app # 应用包
dmg/
<ProductName>_<version>_<arch>.dmg # DMG安装程序