distributing-tauri-for-macos

📁 beshkenadze/claude-code-tauri-skills 📅 14 days ago
1
总安装量
1
周安装量
#51703
全站排名
安装命令
npx skills add https://github.com/beshkenadze/claude-code-tauri-skills --skill distributing-tauri-for-macos

Agent 安装分布

cursor 1
codex 1
claude-code 1
gemini-cli 1

Skill 文档

Tauri macOS Distribution

This skill covers distributing Tauri v2 applications on macOS, including DMG installers and application bundle configuration.

Overview

macOS distribution for Tauri apps involves two primary formats:

  1. Application Bundle (.app) – The executable directory containing all app components
  2. DMG Installer (.dmg) – A disk image that wraps the app bundle for easy drag-and-drop installation

Building for macOS

Build Commands

Generate specific bundle types using the Tauri CLI:

# Build app bundle only
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
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

Application Bundle Structure

The .app directory follows macOS conventions:

<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

DMG Installer Configuration

Configure DMG appearance in tauri.conf.json:

Complete DMG Configuration Example

{
  "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

Option Type Default Description
background string Path to background image relative to src-tauri
windowSize.width number 660 DMG window width in pixels
windowSize.height number 400 DMG window height in pixels
windowPosition.x number Initial window X position on screen
windowPosition.y number Initial window Y position on screen
appPosition.x number 180 App icon X position in window
appPosition.y number 220 App icon Y position in window
applicationFolderPosition.x number 480 Applications folder X position
applicationFolderPosition.y 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.

Info.plist Customization

Creating a Custom Info.plist

Create src-tauri/Info.plist to extend the default configuration. The Tauri CLI automatically merges this with generated values.

<?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

Key Description
NSCameraUsageDescription Camera access explanation
NSMicrophoneUsageDescription Microphone access explanation
NSLocationUsageDescription Location access explanation
NSPhotoLibraryUsageDescription Photo library access explanation
NSAppleEventsUsageDescription AppleScript/automation access
CFBundleDocumentTypes Supported document types
CFBundleURLTypes Custom URL schemes
LSMinimumSystemVersion Minimum macOS version (prefer tauri.conf.json)

Info.plist Localization

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.strings

Example InfoPlist.strings (German):

"NSCameraUsageDescription" = "Diese App benötigt Kamerazugriff für Videoanrufe";
"NSMicrophoneUsageDescription" = "Diese App benötigt Mikrofonzugriff für Audioaufnahmen";

Configure in tauri.conf.json:

{
  "bundle": {
    "resources": {
      "infoplist/**": "./"
    }
  }
}

Entitlements Configuration

Entitlements grant special capabilities when your app is code-signed.

Creating Entitlements.plist

Create src-tauri/Entitlements.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>
    <!-- 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

{
  "bundle": {
    "macOS": {
      "entitlements": "./Entitlements.plist"
    }
  }
}

Common Entitlements Reference

Sandbox Entitlements:

Entitlement Description
com.apple.security.app-sandbox Enable app sandbox (required for App Store)
com.apple.security.network.client Outbound network connections
com.apple.security.network.server Incoming network connections
com.apple.security.files.user-selected.read-write Access user-selected files
com.apple.security.files.downloads.read-write Access Downloads folder

Hardware Entitlements:

Entitlement Description
com.apple.security.device.camera Camera access
com.apple.security.device.microphone Microphone access
com.apple.security.device.usb USB device access
com.apple.security.device.bluetooth Bluetooth access

Hardened Runtime Entitlements:

Entitlement Description
com.apple.security.cs.allow-jit Allow JIT compilation
com.apple.security.cs.allow-unsigned-executable-memory Allow unsigned executable memory
com.apple.security.cs.disable-library-validation Load arbitrary plugins

macOS Bundle Configuration

Complete macOS Configuration Example

{
  "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:

{
  "bundle": {
    "macOS": {
      "minimumSystemVersion": "12.0"
    }
  }
}

Default: macOS 10.13 (High Sierra)

Including Frameworks and Libraries

Bundle system frameworks or custom dylib files:

{
  "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

Adding Custom Files to Bundle

Include additional files in the bundle’s Contents directory:

{
  "bundle": {
    "macOS": {
      "files": {
        "embedded.provisionprofile": "./profile.provisionprofile",
        "SharedSupport/docs/guide.pdf": "./assets/guide.pdf",
        "Resources/config.json": "./config/default.json"
      }
    }
  }
}

Format: "destination": "source" where paths are relative to 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 NS*UsageDescription keys to Info.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

Verification Commands

# Check Info.plist contents
plutil -p path/to/App.app/Contents/Info.plist

# Verify entitlements
codesign -d --entitlements - path/to/App.app

# Check code signature
codesign -vvv --deep --strict path/to/App.app

# View bundle structure
find path/to/App.app -type f | head -50

Quick Reference

File Locations

File Location Purpose
Info.plist src-tauri/Info.plist App metadata extensions
Entitlements.plist src-tauri/Entitlements.plist Capability entitlements
DMG Background Any path in project DMG window background
Localized strings src-tauri/infoplist/<lang>.lproj/ Localized Info.plist values

Build Output Locations

src-tauri/target/release/bundle/
    macos/
        <ProductName>.app         # Application bundle
    dmg/
        <ProductName>_<version>_<arch>.dmg  # DMG installer