Skip to content

tramlinehq/store-quirks

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

56 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

A Collection of Mobile App Store Quirks

License Discord

What is this?

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

Glossary

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.

Apple App Store

Fastlane

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 the inflight 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.

When can you create a new release for an app?

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

What is DEVELOPER_REMOVED_FROM_SALE and how do you get to that state?

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:

remove from sale

Can you revert to an older version of the app if the current version (being phased) has a bug?

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

During a phased release, what version is presented to users downloading for the first time?

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.

From https://developer.apple.com/help/app-store-connect/update-your-app/release-a-version-update-in-phases:

Keep in mind that apps and app updates in phased release can be manually downloaded from the App Store by anyone at any time.

How does the release of a version update work during a phased release?

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.

Is there a way to halt a phased release?

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.

From https://developer.apple.com/help/app-store-connect/update-your-app/release-a-version-update-in-phases:

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 a phased release?

Yes. See Does the previous Ready For Sale in phased release automatically halt or stop when a new one is attempted for distribution after approval?

Can you start a new release (start its distribution) while another release is in phased release, but paused?

Yes. See Does the previous Ready For Sale in phased release automatically halt or stop when a new one is attempted for distribution after approval?

How long can you shepherd a phased release?

Upto 30 days, after which the build is removed.

How long are non-production builds retained for in TestFlight?

They expire after 90 days.

What happens to the phased release when it is paused and the 30 day time limit has passed?

Currently uncertain.

Until what state can you remove a release from review, or cancel it?

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.

remove from review cancel before release

Can I update a build on a running phased rollout?

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.

cancel release

πŸ†• Should the Version Code be unique for every build on TestFlight?

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.

πŸ†• Should the Version Code always be higher than the last one released?

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.

πŸ†• Should the Version Name always be higher than the last one released?

Yes. See explanation here.

πŸ†• Can I cancel an app store submission and update the inflight release right after via the API?

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.


Google Play Store

Can I update a build on a running staged rollout?

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.

During a staged rollout, what version is presented to users downloading for the first time?

New users also participate in the randomization off of the release % bucket.

How does the release of a version update work during a staged rollout?

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.

How long can you shepherd a staged rollout?

Indefinitely.

How long are non-production builds retained for in the App Bundle Explorer?

Indefinitely.

πŸ†• Should the Version Code be unique for every build on App Bundle Explorer?

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.

πŸ†• Should the Version Code for a track always be higher than the last one?

Yes. The release to track would fail with the following error:

Screenshot 2023-05-22 at 10 08 02 PM

πŸ†• Should the Version Name always be higher than the last one released?

Since Play Store treats version names as any raw strings, there is no such constraint.

Help and contribution

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.