As mobile developers, we face unique challenges when it comes to releasing and managing updates for our apps across different app stores. One of the primary reasons for this difficulty is the scattered and insufficient documentation available, which lacks the necessary level of detail and nuance to provide a clear understanding of the process.
Additionally, the interfaces and tools provided by these stores for managing releases are often opaque and and don't offer much insight into how things work behind the scenes, which further complicates the process.
This reference is a compilation of answers for common and rare situations in an attempt to increase transparency. It is compiled from experience, developer forums, Stack Overflow, and various other sources of developer documentation. We hope contributions from other developers will grow this resource further.
Note: A few of these might seem obvious, but they exist to draw a contrast between the stores.
Jump to: App Store β’ Play Store
Newly added quirks: App Store β’ Play Store
This is a quick definition check for commonly used words across stores so that we don't end up using them loosely or interchangeably:
App Store | Play Store | |
---|---|---|
Version Name | Bundle Short Version String. The release or version number of the bundle. String on the right: |
This is versionName . Unlike App Store, it doesn't need to be a semver-style string; it can be anything. This is what is shown to the users on the store page. |
Version Code | Bundle Version String (a.k.a. build string). The version of the build that identifies an iteration of the bundle. This number is the one generally incremented through a CI pipeline. Note that this technically needn't be an integer, it just needs to be incremented every time. Number on the left: |
This is versionCode . Unlike App Store, it is not a string, it is a pure integer that must be incremented for every new build. |
Release Version | This is typically the Version Name (but it can be different). In the APIs, you'd find this under PreReleaseVersion and/or App Store Version. This is what is shown to the users on the store page. | This is typically the Version Name, but can be different. This is only for internal use and isn't shown to users anywhere. |
When using Fastlane, if skip_app_version_update
is set to false
(default), the following two things will happen:
- Creating a new build on TestFlight will auto-create a new release in
READY_FOR_SUBMISSION
on App Store (production). - If there's already an
inflight
release, a new build on TestFlight will not auto-update the build under theinflight
release, but, it will change the release version name to the new one.
Set the flag to true
to disable the above.
Does the previous Ready For Sale in phased release automatically halt or stop when a new one is attempted for distribution after approval?
If the phased release was paused: the older version moves to REPLACED_WITH_NEW_VERSION
status with its phased release as COMPLETE
after a new version is released.
If the phased release was active: same as above.
You can only do this when the last release is in READY_FOR SALE
(it has been released to at least some users, phased or full) or DEVELOPER_REMOVED_FROM_SALE
.
Ref: https://developer.apple.com/help/app-store-connect/update-your-app/create-a-new-version
This state is reached when you have completely removed your app from the store. You can do this by going to the "Pricing and Availability" section in the App Store Connect dashboard and setting the availability to "Remove from sale". This will remove the app from App Store for all regions. Please refer to the screenshot below:
No, it is not possible to revert to a previous version on the App Store if you have an issue with your app. You must create and submit a new version.
Ref: https://developer.apple.com/help/app-store-connect/update-your-app/create-a-new-version
Phased rollout is only for automatic updates, new users will always download the latest build. Existing users can also go and manually update the build from the App Store.
Keep in mind that apps and app updates in phased release can be manually downloaded from the App Store by anyone at any time.
For example, will version 2.1.0 be released to the same 10% of the users that already received version 2.0.0? Or will it be delivered to a completely new set of 10% of my users?
It will be delivered to a completely new random sample of 10% users, no correlation.
In a way, yes. A release can be paused any number of times during a phased rollout, but the halt is immediate and that version is removed from the store right away. Halt will not be able to do anything about the users who already received the update.
While your app is in phased release, you can choose to pause the release for a total of 30 days. Thereβs no limit to the number of pauses.
If you remove your app from sale, phased release will stop and wonβt be available for that version again.
You can make that version available again by flipping the switch. It can take some time to become available again. See What is DEVELOPER_REMOVED_FROM_SALE and how do you get to that state?
Can you start a new release (start its distribution) while another release is in phased release, but paused?
Upto 30 days, after which the build is removed.
They expire after 90 days.
Currently uncertain.
You can remove a release from review even after the build is In Review
. You can cancel a release after approvals and before a Developer Release.
You canβt do this because there is no UI for it on the App Store Connect dashboard.
If you try to do this using the API, you get the following error:
A relationship value is not acceptable for the current resource state.
The specified pre-release build could not be added.
Also from https://developer.apple.com/help/app-store-connect/manage-builds/choose-a-build-to-submit:
However, you can change the build as often as you want until you submit the version to App Review.
Also see: Can you revert to an older version of the app if the current version (being phased) has a bug?
Can I update a build after a release has been reviewed but has not been released to users (not in READY_FOR_SALE
)?
This cannot be done. The build can only be updated before submission for review, after which you have to explicitly cancel the release and make a new one to be able to change builds.
This is partly true. A more general rule of thumb for this is the following:
The version code and version name combination must be unique. In other words, you can have same version codes (build numbers) across different version names.
For example,
Version 1.0.0
- Build 90
- Build 100
Version 1.0.1
- Build 90
- Build 100
- Build 101
The above is a valid scenario.
This is not the case. The version code can be lower than the last version code deployed on App Store as long as the version name is an incremented value from the previous one.
For example,
Current App Store release: 1.0.0 (100)
Valid new release: 1.0.1 (99)
Valid new release: 1.0.1 (100)
Valid new release: 1.0.1 (101)
Invalid new release: 1.0.0 (99)
Invalid new release: 0.0.1 (101)
In the last two invalid cases, a new build upload to TestFlight will fail.
Yes. See explanation here.
Yes. But, in our tests, it's notable that cancelling an app store submission through the API (or developer rejecting it) can actually take a few seconds to register on the Apple side. It may not be internally transactional, hence requires waiting to see that update.
We see that when using the App Store Connect API, if you cancel an existing submission and try and update the details of the now editable app store version right away, it fails. Our guess is this is because the cancel submission API responds without persisting the change and requires a little gap before you can try and update the details of the newly editable app store version.
Yes. This is recommended so that you waste less time overall.
Yes. Starting a new release will simply cancel the existing rollout without additional confirmations.
Play Store allows you to create a new release on the Production track while another is being rolled out. It immediately sets the current release to be in a Not Live
state when the new one is promoted to be the live release.
New users also participate in the randomization off of the release % bucket.
For example, will version 2.1.0 be released to the same 10% of the users that already received version 2.0.0? Or will it be delivered to a completely new set of 10% of my users?
From https://support.google.com/googleplay/android-developer/answer/6346149?hl=en:
When you do a staged rollout of a new release before completing the rollout of the previous release, the new release will use the same group of users as the previous release (depending on the percentage of the rollout).
In the Play Store, depending on the percentage rollout, the user group is sticky with respect to the selection from the previous release.
Indefinitely.
Indefinitely.
Yes. In addition, new version code should be higher than any version codes in App Bundle Explorer, i.e across all release tracks. The upload will fail otherwise. This is because android compares version codes (along with package name) to determine whether an app update is possible or not.
Yes. The release to track would fail with the following error:
Since Play Store treats version names as any raw strings, there is no such constraint.
If you have a correction, a question, or an answer to a question that youβd like to submit, please create an issue! Feel free to drop in to our Discord community if you'd like to chat.