Skip to main content

Releasing to the Apple App Store

This guide walks through releasing a code push app to the Apple App Store and applying a patch to that release.

The app we will be releasing in this guide is Shorebird Clock, our demo code push app. (source)


To follow along with this guide, you will need the following:

  1. An existing Shorebird app. If you don't have one, you can create one by following the code push quickstart guide.
  2. Access to hardware running macOS. This is required to build iOS apps.
  3. A valid Apple Developer account. This is required to release iOS apps.
  4. An app in App Store Connect. See the official documentation for more information about how to create one.
  5. An iOS Distribution certificate. You can create one at
  6. An iOS App Store provisioning profile. See the official documentation for instructions on how to create one.

Specify a development team in Xcode​

To build an iOS app for distribution, we need to specify a development team in Xcode. Open ios/Runner.xcworkspace in Xcode and select the Runner target:

Xcode development team

Creating a release​

Determine the release version​

Navigate to your app on the Shorebird console to see the current set of releases. For our app, we see that the latest release version is 1.0.3.+1, so the version of our next release will be 1.0.4+1.

Create a release in App Store Connect​

Because the App Store does not include the build number (the +1 part of 1.0.4+1) in app versions, this will show up in the App Store as 1.0.4. Follow the instructions in the official documentation to create a new version in App Store Connect.

App Store Connect version

Update the version in pubspec.yaml​

Update the version in pubspec.yaml to 1.0.4+1:

 name: shorebird_clock
description: A demo app for Shorebird
- version: 1.0.3+1
+ version: 1.0.4+1

Create a Shorebird release​

Create a Shorebird release by running the shorebird release ios-alpha command:

$ shorebird release ios-alpha
[WARN] iOS support is in an alpha state. See for more information.
βœ“ Fetching apps (0.1s)
βœ“ Building release (56.2s)
βœ“ Getting release version (37ms)
βœ“ Fetching releases (0.1s)
πŸš€ Ready to create a new release!
πŸ“± App: time_shift (f2184ee6-9a85-498c-bfeb-114d638c462e)
πŸ“¦ Release Version: 1.0.4+1
πŸ•ΉοΈ Platform: ios

Would you like to continue? (y/N) Yes
βœ“ Fetching Flutter revision (36ms)
βœ“ Creating release (0.2s)
βœ“ Creating artifacts (8.0s)
βœ“ Updating release status (57ms)

βœ… Published Release!

Your next step is to upload your app to App Store Connect.

To upload to the App Store, do one of the following:
1. Open build/ios/archive/Runner.xcarchive in Xcode and use the "Distribute App" flow.
2. Drag and drop the build/ios/ipa/time_shift.ipa bundle into the Apple Transporter macOS app (
3. Run xcrun altool --upload-app --type ios -f build/ios/ipa/time_shift.ipa --apiKey your_api_key --apiIssuer your_issuer_id.
See "man altool" for details about how to authenticate with the App Store Connect API key.

If you perform your own codesigning and do not want Shorebird to codesign your app, you can pass the --no-codesign flag to the shorebird release ios-alpha command. Because only signed code can be run on iOS devices, releases created this way will not be previewable using the shorebird preview command. You can still download and run these releases through TestFlight.

Upload to the App Store​

Open the .xcarchive in Xcode and use the "Distribute App" flow:

Xcode Organizer

As of Xcode 15, you will make the following choices:

  1. "Custom" as the distribution method. Xcode distribution method 1
  2. "App Store Connect" as the distribution method. Xcode distribution method 2
  3. "Upload" as the destination. Upload destination
  4. A few distribution options that are up to you. Importantly, Manage Version and Build Number must be unchecked for Shorebird to work. Because Shorebird targets patches at specific release versions, changing the version or build number will prevent your app from receiving patches. Xcode distribution options
  5. Automatically manage signing or manually manage signing. This is up to you. If you choose to manually manage signing, you will need to select the appropriate development team, provisioning profile, and signing certificate for your app.
  6. Confirm the upload.

Xcode will upload your archive, and if no issues are found, will show a message telling you that the upload was successful:

Xcode upload succeeded

After a short delay (usually a minute or two), you will see the build listed as "Processing" in App Store Connect:

App Store Connect Processing

Once the app has finished processing, we can add it to our release:

App Store Connect add build

Submit the app for review​

When we attempt to submit the app for review, App Store Connect will list the issues we need to resolve before we can submit the app:

App Store Connect review issues

After the release is approved​

Once the release has been approved, you will be able to download it from the App Store.

Creating a patch​

Patches can be pushed to fix bugs in the App Store release without requiring a new submission to the App Store.

Make code changes​

For the purposes of this guide, we will change the default clock face to generative in lib/main.dart:

     (clock) => == clockName,
- orElse: () => ClockFace.particle,
+ orElse: () => ClockFace.generative,

Create a Shorebird patch​

To make this patch available to your users, run shorebird patch ios-alpha.

$ shorebird patch ios-alpha
[WARN] iOS support is in an alpha state. See for more information.
βœ“ Fetching apps (0.4s)
βœ“ Building release (61.5s)
βœ“ Detected release version 1.0.4+1 (44ms)
βœ“ Fetching releases (0.1s)
βœ“ Fetching Flutter revision (23ms)

πŸš€ Ready to publish a new patch!

πŸ“± App: time_shift (f2184ee6-9a85-498c-bfeb-114d638c462e)
πŸ“¦ Release Version: 1.0.4+1
πŸ“Ί Channel: stable
πŸ•ΉοΈ Platform: ios [aarch64 (4.17 MB)]

Would you like to continue? (y/N) Yes
βœ“ Creating patch (72ms)
βœ“ Uploading artifacts (0.5s)
βœ“ Fetching channels (58ms)
βœ“ Promoting patch to stable (61ms)

βœ… Published Patch!