Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
f8ce9c6
wip
lucasfernog Aug 10, 2024
deaece5
Merge remote-tracking branch 'origin/v2' into feat/signing
lucasfernog Aug 10, 2024
4ba79e5
Merge remote-tracking branch 'origin/v2' into feat/signing
lucasfernog Aug 23, 2024
dee0444
document automatic iOS signing
lucasfernog Aug 23, 2024
6e055ed
document cert types
lucasfernog Aug 23, 2024
1a6239d
change titles
lucasfernog Aug 23, 2024
83889bc
port linux signing from v1
lucasfernog Aug 23, 2024
be4cd11
update env vars
lucasfernog Aug 23, 2024
03999e4
update macos signing doc with v1 information
lucasfernog Aug 23, 2024
d5250b2
update android docs
lucasfernog Aug 23, 2024
4e8e294
same password
lucasfernog Aug 24, 2024
45ec39f
feat: add App Store distribution docs for both macOS and iOS
lucasfernog Aug 24, 2024
a4e5d6c
add ITSAppUsesNonExemptEncryption
lucasfernog Aug 24, 2024
6fe18bc
add dmg stub
lucasfernog Aug 24, 2024
4b4b605
add icon section
lucasfernog Aug 24, 2024
2079140
add note on build --open
lucasfernog Aug 24, 2024
ce3a285
add macos app bundle docs
lucasfernog Aug 24, 2024
03ba3c3
link the app bundle docs in the app store guide
lucasfernog Aug 24, 2024
8d279a5
add dmg docs
lucasfernog Aug 24, 2024
8380441
properties is already imported now
lucasfernog Aug 25, 2024
b503a58
use command tabs
lucasfernog Aug 25, 2024
9241f1c
add title to json codes
lucasfernog Aug 25, 2024
fea9b1b
use commandtabs for tauri icon
lucasfernog Aug 25, 2024
57b0ad0
use build/bundle
lucasfernog Aug 25, 2024
f219147
missing quote
lucasfernog Aug 25, 2024
c110bb1
add ins
lucasfernog Aug 25, 2024
88a0439
add dmg icon position section
lucasfernog Aug 25, 2024
c5b6392
Apply suggestions from code review
lucasfernog Aug 26, 2024
fb6a501
apply changes from code review
lucasfernog Aug 26, 2024
0129b6c
cleanup linux signing
lucasfernog Aug 26, 2024
47579f3
Merge remote-tracking branch 'origin/v2' into feat/signing
lucasfernog Aug 26, 2024
fc15aae
update overview
lucasfernog Aug 26, 2024
46dae31
Merge branch 'feat/signing' into feat/app-store
lucasfernog Aug 26, 2024
a859c6e
update overview
lucasfernog Aug 26, 2024
0b13409
Merge branch 'v2' into feat/app-store
lucasfernog Aug 27, 2024
47dec2c
Apply suggestions from code review
lucasfernog Aug 27, 2024
360433c
remove newline
lucasfernog Aug 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
316 changes: 311 additions & 5 deletions src/content/docs/distribute/app-store.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,317 @@
title: App Store
sidebar:
order: 1
badge:
text: Stub
variant: caution
---

import Stub from '@components/Stub.astro';
import CommandTabs from '@components/CommandTabs.astro';

<Stub />
The [Apple App Store] is the app marketplace maintained by Apple.
You can distribute your Tauri app targeting macOS and iOS via this App Store.

This guide only covers details for distributing apps directly to the App Store.
See the general [App Bundle][App Bundle distribution guide] for more information on macOS distribution options and configurations.

## Requirements

Distributing iOS and macOS apps requires enrolling to the [Apple Developer] program.

Additionally, you must setup code signing for [macOS][macOS code signing] and [iOS][iOS code signing].

## Changing App Icon

After running `tauri ios init` to setup the Xcode project, you can use the `tauri icon` command to update the app icons.

<CommandTabs
npm="npm run tauri icon /path/to/app-icon.png --ios-color #fff"
yarn="yarn tauri icon /path/to/app-icon.png --ios-color #fff"
pnpm="pnpm tauri icon /path/to/app-icon.png --ios-color #fff"
cargo="cargo tauri icon /path/to/app-icon.png --ios-color #fff"
/>

The `--ios-color` argument defines the background color for the iOS icons.

## Setting up

After enrolling to the Apple Developer program, the first step to distribute your Tauri app in the App Store
is to register your app in the [App Store Connect][app-store-connect-apps].

:::note
The value provided in the _Bundle ID_ field **must** match the identifier defined in [`tauri.conf.json > identifier`].
:::

## Build and upload

The Tauri CLI can package your app for macOS and iOS. Running on a macOS machine is a requirement.

:::caution
Code signing is required. See the documentation for [macOS][macOS code signing] and [iOS][iOS code signing].
:::

Note that Tauri leverages Xcode for the iOS app so you can use Xcode to archive and distribute for iOS instead of the Tauri CLI.
To open the iOS project in Xcode for building you must run the following command:

<CommandTabs
npm="npm run tauri ios build --open"
yarn="yarn tauri ios build --open"
pnpm="pnpm tauri ios build --open"
cargo="cargo tauri ios build --open"
/>

### macOS

To upload your app to the App Store, first you must ensure all required configuration options are set
so you can package the App Bundle, create a signed `.pkg` file and upload it.

The following sections will guide you through the process.

#### Setup

Your app must include some configurations to be accepted by the App Store verification system.

:::tip
The following sections guides you through configuring your app for App Store submissions.

To apply the following config changes only when building for App Store, you can create a separate Tauri configuration file:

```json title="src-tauri/tauri.appstore.conf.json
{
"bundle": {
"macOS": {
"entitlements": "./Entitlements.plist",
"files": {
"embedded.provisionprofile": "path/to/profile-name.provisionprofile"
}
}
}
}
```

Then merge that config file with the main one when bundling your Tauri app for App Store:

<CommandTabs
npm="npm run tauri build --no-bundle
npm run tauri bundle --bundles app --target universal-apple-darwin --config src-tauri/tauri.appstore.conf.json"
yarn="yarn tauri build --no-bundle
yarn tauri bundle --bundles app --target universal-apple-darwin --config src-tauri/tauri.appstore.conf.json"
pnpm="pnpm tauri build --no-bundle
pnpm tauri bundle --bundles app --target universal-apple-darwin --config src-tauri/tauri.appstore.conf.json"
cargo="cargo tauri build --no-bundle
cargo tauri bundle --bundles app --target universal-apple-darwin --config src-tauri/tauri.appstore.conf.json"
/>

This is particularly useful when setting up your CI/CD to upload your app to the App Store while not requiring the provision profile locally or
when compiling the app for distribution outside the App Store.

:::

- Category

Your app must define its [`tauri.conf.json > bundle > category`] to be displayed in the App Store:

```json title="tauri.conf.json" ins={3}
{
"bundle": {
"category": "Utility"
}
}
```

- Provisioning profile

You must also create a provisioning profile for your app to be accepted by Apple.

In the [Identifiers](https://developer.apple.com/account/resources/identifiers/list) page,
create a new App ID and make sure its "Bundle ID" value matches the identifier set in [`tauri.conf.json > identifier`].

Navigate to the [Profiles](https://developer.apple.com/account/resources/profiles/list) page to create a new provisioning profile.
For App Store macOS distribution, it must be a "Mac App Store Connect" profile.
Select the appropriate App ID and link the certificate you are using for code signing.

After creating the provisioning profile, download it and save it to a known location and configure Tauri to include it in your app bundle:

```json title="tauri.conf.json" ins={4-6}
{
"bundle": {
"macOS": {
"files": {
"embedded.provisionprofile": "path/to/profile-name.provisionprofile"
}
}
}
}
```

- Info.plist

Your app must comply with encryption export regulations.
See the [official documentation](https://developer.apple.com/documentation/security/complying-with-encryption-export-regulations?language=objc)
for more information.

Create a Info.plist file in the src-tauri folder:

```xml
<?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>ITSAppUsesNonExemptEncryption</key>
<false/> # or `true` if your app uses encryption
</dict>
</plist>
```

- Entitlements

Your app must include the App Sandbox capability to be distributed in the App Store.
Additionally, you must also set your App ID and Team ID in the code signing entitlements.

Create a `Entitlements.plist` file in the `src-tauri` folder:

```xml
<?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.application-identifier</key>
<string>$TEAM_ID.$IDENTIFIER</string>
<key>com.apple.developer.team-identifier</key>
<string>$TEAM_ID</string>
</dict>
</plist>
```

Note that you must replace `$IDENTIFIER` with the [`tauri.conf.json > identifier`] value
and `$TEAM_ID` with your Apple Developer team ID, which can be found in the `App ID Prefix` section in the
[Identifier](https://developer.apple.com/account/resources/identifiers/list) you created for the provisioning profile.

And reference that file in the macOS bundle configuration [`tauri.conf.json > bundle > macOS > entitlements`]:

```json title="tauri.conf.json" ins={4}
{
"bundle": {
"macOS": {
"entitlements": "./Entitlements.plist"
}
}
}
```

You now must build your application with code signing enabled for the entitlements to apply.

Make sure your app works when running in an App Sandbox context.

#### Build

You must upload your macOS application as a `.pkg` file to the App Store.
Run the following command to package your app as a macOS App Bundle (`.app` extension):

```
tauri build --bundles app --target universal-apple-darwin
```

:::note
The above command creates an Universal App Binary application, supporting both Apple Silicon and Intel processors.

If you prefer to only support Apple Silicon instead, you must change [`tauri.conf.json > bundle > macOS > minimumSystemVersion`] to `12.0`:

```json title="tauri.conf.json" ins={4}
{
"bundle": {
"macOS": {
"minimumSystemVersion": "12.0"
}
}
}
```

And change the CLI command and output path based on the Mac system you are running:

- if your build system uses an Apple Silicon chip, remove the `--target universal-apple-darwin` arguments and use `target/release`
instead of `target/universal-apple-darwin/release` in the paths referenced below.
- if your build system uses an Intel chip:
- install the Rust Apple Silicon target:
```
rustup target add aarch64-apple-darwin
```
- change the `universal-apple-darwin` argument to `aarch64-apple-darwin`
and use `target/aarch64-apple-darwin/release` instead of `target/universal-apple-darwin/release` in the paths referenced below.

:::

See the [App Bundle distribution guide] for more information on configuration options.

To generate a signed `.pkg` from your app bundle, run the following command:

```
xcrun productbuild --sign "<certificate signing identity>" --component "target/universal-apple-darwin/release/bundle/macos/$APPNAME.app" /Applications "$APPNAME.pkg"
```

Note that you must replace _$APPNAME_ with your app name.

:::note
You must sign the PKG with a _Mac Installer Distribution_ signing certificate.
:::

#### Upload

Now you can use the [`altool`] CLI to upload your app PKG to the App Store:

```
xcrun altool --upload-app --type macos --file "$APPNAME.pkg" --apiKey $APPLE_API_KEY_ID --apiIssuer $APPLE_API_ISSUER
```

Note that `altool` requires an App Store Connect API key to upload your app.
See the [authentication section] for more information.

Your app will then be validated by Apple and available in TestFlight if approved.

### iOS

To build your iOS app, run the `tauri ios build` command:

<CommandTabs
npm="npm run tauri ios build --export-method app-store-connect"
yarn="yarn tauri ios build --export-method app-store-connect"
pnpm="pnpm tauri ios build --export-method app-store-connect"
cargo="cargo tauri ios build --export-method app-store-connect"
/>

The generated IPA file can be found in `src-tauri/gen/apple/build/arm64/$APPNAME.ipa`.

Note that you must replace _$APPNAME_ with your app name.

Now you can use the `altool` CLI to upload your iOS app to the App Store:

```
xcrun altool --upload-app --type ios --file "src-tauri/gen/apple/build/arm64/$APPNAME.ipa" --apiKey $APPLE_API_KEY_ID --apiIssuer $APPLE_API_ISSUER
```

Note that `altool` requires an App Store Connect API key to upload your app.
See the [authentication section] for more information.

Your app will then be validated by Apple and available in TestFlight if approved.

### Authentication

The iOS and macOS apps are uploaded using `altool`, which uses an App Store Connect API key to authenticate.

To create a new API key, open the [App Store Connect's Users and Access page], select the Keys tab, click on the Add button and select a name and the Developer access.
The `APPLE_API_ISSUER` (Issuer ID) is presented above the keys table, and the `APPLE_API_KEY_ID` is the value on the Key ID column on that table.
You also need to download the private key, which can only be done once and is only visible after a page reload (the button is shown on the table row for the newly created key).
The private key file path must be saved as `AuthKey\_<APPLE_API_KEY_ID>.p8` in one of these directories:`<current-working-directory>/private_keys`, `~/private_keys`, `~/.private_keys`or`~/.appstoreconnect/private_keys`.

[App Bundle distribution guide]: /distribute/macos-application-bundle
[Apple Developer]: https://developer.apple.com
Comment thread
lucasfernog marked this conversation as resolved.
[Apple App Store]: https://www.apple.com/store
[`altool`]: https://help.apple.com/itc/apploader/#/apdATD1E53-D1E1A1303-D1E53A1126
[macOS code signing]: /distribute/signing/macos
[iOS code signing]: /distribute/signing/ios
[app-store-connect-apps]: https://appstoreconnect.apple.com/apps
[`tauri.conf.json > identifier`]: /reference/config/#identifier
[`tauri.conf.json > bundle > category`]: /reference/config/#category
[`tauri.conf.json > bundle > macOS > entitlements`]: /reference/config/#entitlements
[`tauri.conf.json > bundle > macOS > minimumSystemVersion`]: /reference/config/#minimumsystemversion
[App Store Connect's Users and Access page]: https://appstoreconnect.apple.com/access/users
[authentication section]: #authentication
Loading