# Xcode previews

Build your application, then use `tuist share` to publish it to your Tuist project. Connect your project first using the <.localized_link href="/guides/get-started/existing-xcode-project">existing Xcode project</.localized_link> or <.localized_link href="/guides/get-started/generated-xcode-project">generated project</.localized_link> guide.

## Build and share

For a Tuist-generated project:

```bash
tuist generate App
tuist xcodebuild build -scheme App -workspace App.xcworkspace \
  -configuration Debug -sdk iphonesimulator
tuist share App
```

For an existing Xcode project:

```bash
tuist xcodebuild build -scheme App -project App.xcodeproj \
  -configuration Debug -sdk iphonesimulator
tuist share App --configuration Debug --platforms iOS
```

Replace the scheme, project, and workspace names with your own. To share a Release build, use `-configuration Release` when building and `--configuration Release` when sharing.

## Physical devices

You are responsible for signing device builds with a provisioning profile that allows installation on the recipient's device. Build with a device destination instead of the simulator SDK:

```bash
tuist xcodebuild build -scheme App -project App.xcodeproj \
  -configuration Debug -destination 'generic/platform=iOS'
tuist share App --configuration Debug --platforms iOS
```

You can also share an already exported IPA:

```bash
tuist share App.ipa
```

Recipients can open an IPA preview link on their mobile device to install the application. Authentication and the project's preview visibility still apply.

## CI and build numbers

Use your existing <.localized_link href="/guides/integrations/continuous-integration">CI authentication</.localized_link> and make `CFBundleVersion` unique for each new build. For example, use GitHub Actions' <code v-pre>${{ github.run_number }}</code>. Uploading the same binary and build number again through `tuist share` fails rather than creating a duplicate.

```bash
tuist share App --track beta --release-notes "Fix sign-in"
```

See <.localized_link href="/guides/features/previews#run-a-preview">Run a preview</.localized_link> for running published builds, access, tracks, and README badges.

## Tracks with tuist share {#share-tracks}

For workflows that publish with `tuist share`, use `--track` to select a track:

```bash
tuist share App --track beta
tuist share App --track nightly
```

## Release notes {#release-notes}

Use tracks for environment groups and release notes for the purpose of an individual build:

```bash
tuist share App --track QA --release-notes "Fix sign-in and improve the checkout flow"
```

Replace `App` with your app name, application file path, or executable distribution and its `--executable` option. Release notes are optional plain text, up to 10,000 characters. The first nonblank line appears as a single-line snippet in preview lists, so build numbers and other identifying information are visible at a glance. Long lines are truncated; full notes appear on the detail pages. Search matches display names and full release notes, including lines not shown in the snippet. Multiline notes are supported, for example `--release-notes "$(< release-notes.txt)"`. They do not change the app's display name or its track.

### Compatibility {#preview-metadata-compatibility}

Release notes are additive metadata, not part of a preview's identity. Uploads from old and new clients still group into the same preview across platforms. The first nonblank notes are retained: a later upload can fill notes that were previously absent, but cannot overwrite existing notes. Omitting `release_notes`, sending `null`, or sending an empty or whitespace-only string never clears notes. Existing previews are not backfilled and remain valid without notes.

The list API's optional `track` query parameter matches a whole track name, case-insensitively, consistent with existing track storage. Omit it or send an empty value (`?track=`) to list all tracks. Track names remain open strings, not a fixed list of values. `GET /api/projects/:account_handle/:project_handle/previews/tracks` returns `{total_count, tracks: [{name, count}]}` with sorted, case-insensitively grouped named tracks, under the same preview-read authorization as listing builds. Counts cover the whole project independently of pagination, search, and the selected track; the total includes untracked previews. Only listable previews with a bundle identifier are counted. The list API also accepts optional `search` for a literal, case-insensitive substring of the display name or full release notes, combined with the track before pagination. Existing `display_name` filtering remains exact.

Old clients can continue uploading and listing previews without sending either field. New clients accept older responses that omit track or notes, and ignore unknown response properties added by future servers. API integrations should likewise ignore unknown response properties so additive metadata remains compatible.

Self-hosted deployments need a server version that supports release notes and track filtering, together with an updated client, to use these features. Older servers may ignore notes or unknown query parameters.

## Pull/merge request comments {#pullmerge-request-comments}

> [!WARNING]
> **Integration With Git Platform Required**
>
> To get automatic pull/merge request comments, integrate your <.localized_link href="/guides/server/accounts-and-projects">remote project</.localized_link> with a <.localized_link href="/guides/server/authentication">Git platform</.localized_link>.

Once your Tuist project is connected with your Git platform, add <.localized_link href="/cli/share">`tuist share`</.localized_link> after a successful application build in CI. Tuist will post a preview link directly in your pull/merge requests, so reviewers can test without building locally:

![GitHub app comment with a Tuist Preview link](/images/guides/features/github-app-with-preview.png)

## Automations {#automations}

Use `--json` to get JSON output from `tuist share`:

```bash
tuist share --json
```

Use the result for custom automations, such as posting a Slack message from CI. The `url` key contains the full preview link; `qrCodeURL` points to a QR code image for opening the preview on a device:

```json
{
  "id": 1234567890,
  "url": "https://cloud.tuist.io/preview/1234567890",
  "qrCodeURL": "https://cloud.tuist.io/preview/1234567890/qr-code.svg"
}
```


Recipients can use the <.localized_link href="/guides/features/previews/run/macos">Tuist macOS app</.localized_link> or <.localized_link href="/guides/features/previews/run/ios">iPhone app</.localized_link> independently of the build-system integration. The iPhone guide also covers <.localized_link href="/guides/features/previews/run/ios#in-app-update-notifications">in-app update notifications</.localized_link> with the Tuist SDK.
