Step By Step Instructions
This is step by step instructions on how to create, sign and upload a Tauri application to the Apple Store. At the end of this, you should understand all the steps involved and then be able to successfully upload your own app. That is the goal at any rate. The first Tauri app I deployed to the Apple app store was an absolute nightmare. It took far longer to work out all the details than I'm willing to admit here. In the hopes of saving you many of wasted hours, here is what I finally did to get my f***ing app in the app store! You can skip all the detail and see the bare bone steps here.Not Included
I will not cover things that need to be done on the Apple Dev / Apple Store side. I'll include some links and comments where needed but don't expect any details.In 10 Steps
- Create the Certificates
- Create Provisioning File
- Create entitlements.plist
- Configure tauri.conf.json
- Set Version Number
- Create the App Bundle
- Add Provisioning Profile
- Sign the App Bundle
- Create Signed Package
- Upload
What You Need
Apple Account:- An Active Apple Account (duh)
- Apple Distribution Certificate
- 3rd Party Mac Developer Installer Certificate
- embedded.provisionprofile
- entitlements.plist
- Your_App_Name.app
- Xcode (required)
- Transporter (optional)
Xcode
Use Xcode. Yes, use Xcode. No matter what you do, you will need Xcode installed on your system. You'll need it to run the command line tools used here. You may also want to use it for creating and managing certificates. Once you've figured out where to go, it becomes a quick and easy process. Needed For:- Creating Certificates
- Command Line Tools for Signing, Uploading
1 - Certificates
Use Xcode! I found Xcode the easiest way to create certificates. Defining them inside Xcode was the most pain free way to do it. You can create your certificates on your Apple account online, and then download them. However, I couldn't get this to work correctly. The certs didn't seem properly signed with Apple's certificate issuer. Maybe somebody smarter than me can tell me how to do it. Certificates:- Apple Development Certificate
- 3rd Party Mac Developer Installer Certificate
Signs the app bundle.
3rd Party Mac Developer Installer Certificate:
Signs the upload package.
From Xcode:
Menu:
Xcode ->
Settings... ->
Accounts (Tab) ->
Manage Certificates... (Button)
2 - Create Provisioning Profile
Create and download a provisioning profile for your application on your Apple dev account. Apple Dev: Your Provisioning Profiles3 - Create Entitlements
You need to create and add an entitlements file to your .app bundle. Apple will use this to determine what privileges your app needs and this information becomes part of the application signature once signed. At a minimum you will need com.apple.security.app-sandbox and com.apple.security.network.client. Apple Docs: Entitlements File Name:entitlements.plist
Sample Contents with Minimum Requirements:
<?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>com.apple.security.app-sandbox</key><true/>
<key>com.apple.security.network.client</key><true/>
</dict>
</plist>
4 - Configure Tauri
Set up the following items in your tauri.conf.json file.- productName
- version
- copyright
- identifier
- entitlements
The app identifier set up by you in your Apple account under Certificates, Identifiers & Profiles.
Apple Dev: Your Certificates, Identifiers & Profiles
Version:
The version number you set up in your Apple account. From the App settings, click + on the top left to add a new version.
Apple Dev: Your Applications
Tauri Docs: Configuration
File:
src-tauri/tauri.conf.json
Add These:
{
"package": {
"productName": "App Name",
"version": "1.2.3"
},
"tauri": {
"bundle": {
"copyright": "Copyright © 2023 ...",
"identifier": "io.domain.app-name",
"macOS": {
"entitlements": "../entitlements.plist",
},
},
}
}
Sample:
{
"package": {
"productName": "Encode Escape",
"version": "1.0.11"
},
"tauri": {
"bundle": {
"copyright": "Copyright © 2023 ThinkGo LLC",
"identifier": "io.thinkgo.encode-escape",
"macOS": {
"entitlements": "../entitlements.plist",
},
},
}
}
5 - Set / Update Version Number
Set up the version number to match the one you added on your App settings on your Apple account. Apple Dev: Your Applications Update these project files:package.json
src-tauri/Cargo.toml
src-tauri/tauri.conf.json
package.json:
"version": "1.2.3",
src-tauri/Cargo.toml:
version = "1.2.3"
src-tauri/tauri.conf.json:
"version": "1.2.3"
package.json:
- NPM Version Number
- Use By Cargo Build
- Sets the rlib Version Number
- About Version Number
- Install Version Number
- info.plist Version Number (MacOS)
6 a - Create the App Bundle
Skip if you already have your app bundle (Your_App_Name.app). The actual command depends on how you created and run your Tauri builds. Create the app bundle if using NPM:npm run tauri build
Find Here in Your Project Directory:
"src-tauri/target/release/bundle/macos/Your_App_Name.app
6 b - Create the App Bundle - Universal Binary
Create a universal bundle if using NPM:npm run tauri build -- --target universal-apple-darwin
Find It Here:
"/src-tauri/target/universal-apple-darwin/release/bundle/macos/Your_App_Name.app
7 - Add Provisioning Profile
Copy your provisioning file into your app bundle. File:embedded.provisionprofile
Copy into the app bundle:
Your_App_Name.app/Contents/embedded.provisionprofile
8 - Sign The App Bundle
Sign the completed app bundle with your apple distribution certificate:codesign \
--sign "APPLE_DISTRIBUTION_CERT_NAME" \
--entitlements "entitlements.plist" \
"Your_App_Name.app/Contents/MacOS/Your_App_Name"
Sample:
codesign \
--sign "Apple Distribution: ThinkGo LLC (12A3BC4DEF)" \
--entitlements "entitlements.plist" \
"Encode Escape.app/Contents/MacOS/Encode Escape"
9 - Create Signed Package
Create and sign the final package. This is what you will upload to the App Store.productbuild \
--sign "3RD_PARTY_MAC_DEVELOPER_INSTALLER_CERT" \
--component "Your_App_Name.app" "/Applications" \
"Your_App_Name.pkg"
Sample:
productbuild \
--sign "3rd Party Mac Developer Installer: ThinkGo LLC (12A3BC4DEF)" \
--component "Encode Escape.app" "/Applications" \
"Encode Escape.pkg"
10 a - Upload with Transformer
Transformer is the easiest way to upload your app. As long as everything worked in the previous steps, Transformer will accept and upload your signed package file. It can be a bit finicky and doesn't always give good error messages. Steps:- Open Transporter.
- Drag your package onto it.
- Click 'Upload'
10 b - Upload Using xcrun altool
Use xcrun altool if you need to automate the uploading to Apple. It is more work than Transporter. The trickiest part will be getting the app-bundle-version from Info.plist and passing it as a parameter to xcrun. apple-app-id - Get from your Apple account. app-bundle-version - Get from Info.plist inside the app bundle (CFBundleVersion property) App Bundle ID: From Info.plist:<key>CFBundleVersion</key>
<string>20230224.022525</string>
Command:
xcrun altool \
--upload-package "APP_PACKAGE" \
--type macos \
--apple-id "APP_APPLE_ID" \
--bundle-version "APP_BUNDLE_VERSION" \
--bundle-short-version-string "APP_VERSION" \
--bundle-id "APP_BUNDLE_ID" \
-u "USER" \
-p "PASSWORD"
Sample:
xcrun altool \
--upload-package "encode_escape_1.0.11.pkg" \
--type macos \
--apple-id "1665205132" \
--bundle-version "20230224.022525" \
--bundle-short-version-string "1.0.11" \
--bundle-id "io.thinkgo.encode-escape" \
-u "some-apple-id@thinkgo.io" \
-p "abcd-efgh-ijkl-mnop"
Everything, Everywhere, All at Once
All on a Bash Script:# Set These:
APP_NAME="Your App Name Here"
PROJECT_DIR="/path/to/tauri/project"
APP_APPLE_ID="1234567890"
APP_BUNDLE_VERSION="20011231.120101"
APP_VERSION="1.2.3"
APP_BUNDLE_ID="com.domain.app-name"
USER="your-apple-id@domain.com"
PASSWORD="abcd-efgh-ijkl-mnop"
$APPLE_DISTRIBUTION_CERT="Apple Distribution: Your Cert Name Here"
$THIRD_PARTY_MAC_DEVELOPER_CERT="3rd Party Mac Developer Installer: Your Cert Name Here"
# Change if needed:
APP_BUNDLE="$APP_NAME.app"
APP_EXECUTABLE="$APP_BUNDLE/Contents/MacOS/$APP_NAME"
APP_PACKAGE="$APP_NAME.pkg"
# Build, Sign, Package, Upload:
npm run tauri build -- --target universal-apple-darwin
cp "$PROJECT_DIR/src-tauri/target/universal-apple-darwin/release/bundle/macos/$APP_BUNDLE" .
cp "embedded.provisionprofile" "$APP_BUNDLE/Contents/embedded.provisionprofile"
codesign \
--sign "$APPLE_DISTRIBUTION_CERT" \
--entitlements "entitlements.plist" \
"$APP_EXECUTABLE"
productbuild \
--sign "$THIRD_PARTY_MAC_DEVELOPER_CERT" \
--component "$APP_BUNDLE" "/Applications" \
"$APP_PACKAGE"
xcrun altool \
--upload-package "$APP_PACKAGE" \
--type macos \
--apple-id "$APP_APPLE_ID" \
--bundle-version "$APP_BUNDLE_VERSION" \
--bundle-short-version-string "$APP_VERSION" \
--bundle-id "$APP_BUNDLE_ID" \
-u "$USER" \
-p "$PASSWORD"
Links
App Store: Apple Dev Account: Apple Docs: SpeedSheets:Rust SpeedSheet
Tauri SpeedSheet (a work in progress)