Teams that have built many web services often see their schedule slip the first time they take on an app project. The number of screens is similar and so are the features, yet it still happens.
The cause is not development difficulty but the difference in how releases work. On the web, a fix reaches every user the moment you make it. Apps do not work that way. The build has to pass review, users have to install the update, and those who do not keep using the old version.
This one difference affects schedule, design, and operations across the board. This article covers what you need to plan differently from the web when preparing an app project.
1. Releases are not immediate
This is the biggest difference, and most of the others follow from it.
A review stage is added
To publish on an app store, you have to pass review. This stage exists separately from the development schedule.
Points to consider when building it into the schedule:
- The time review takes is not fixed
- You can be rejected. If you fix and resubmit, the wait starts over from the beginning
- Incomplete submission information makes it take longer. A missing review account or missing setup instructions is the typical case
- Each store has different criteria and turnaround times
Neither store guarantees a review time. What the official documentation gives is statistics and caveats (checked October 13, 2026).
| Store | Wording in the official documentation | How to reflect it in the schedule |
|---|---|---|
| App Store | On average, more than 50% of submissions are reviewed within 24 hours and 90% within 48 hours. An incomplete submission may be delayed or may not pass (App Review) | Do not schedule on the average; reserve time that includes one rejection and a re-review |
| Google Play | For some developer accounts, review can take up to 7 days, or longer in exceptional cases (Play Console Help: Publish your app) | For the first release from a new account, reserve a separate week or more |
The App Store Review Guidelines state that review takes longer when an app is repeatedly rejected for the same guideline violation (App Review Guidelines, revision of June 8, 2026). Resubmitting with only the explanation changed, without fixing the reason for rejection, pushes the schedule back further.
Scheduling a demo for the day review is expected to finish is risky. A single rejection is enough to shake the schedule. It is safer to verify first through an internal distribution channel and leave slack for the store release.
Open an internal distribution channel first
Demos and acceptance testing run on a path separate from public store review. The conditions for the test distribution each store provides are as follows (checked October 13, 2026).
| Type | Audience and limits | Review | Notes |
|---|---|---|---|
| TestFlight internal testers | Up to 100 App Store Connect users | Beta build review applies when you invite external testers | The client's staff must be registered as App Store Connect users |
| TestFlight external testers | Up to 10,000 | The first build added to a group goes through review. A full review may be skipped for later builds | Builds can be tested for up to 90 days |
| Google Play internal testing | Up to 100 per app | May not be subject to the standard policy and security reviews | New builds reach testers within minutes |
| Google Play closed testing | Managed by email list | After the first publish, it can take several hours for the test link to become available | For new personal accounts, this stage is a prerequisite for a production release (see Section 6) |
(TestFlight overview, Play Console Help: Set up testing)
The 90-day expiry of TestFlight builds often catches teams out during long acceptance periods. If acceptance testing runs long, put uploading a new build before expiry on the schedule.
Rejection reasons are mostly predictable
These can be avoided if you know them in advance.
| Type | Details |
|---|---|
| Review account | The app requires login but no account is provided for the reviewer |
| Incomplete features | "Coming soon" screens, buttons that do nothing |
| Insufficient permission explanation | It is unclear why camera, location, or notification permission is requested |
| Privacy policy | The link is missing or does not match the data actually collected |
| Payment policy | Digital goods are handled through external payment |
| Content | The age rating does not match the actual content |
| Account deletion | Sign-up is possible in the app, but withdrawal is only possible through customer support |
| Links and screens | Broken links, screenshots that differ from the actual screens |
Of these, a missing review account and insufficient permission explanations are especially common. Putting them on the pre-submission checklist can save you one rejection. Apple states that more than 40% of unresolved review issues relate to Guideline 2.1 (App Completeness) (App Review, checked October 13, 2026). "Coming soon" screens, broken links, and missing review accounts all fall under this item.
The payment item needs its scope read precisely. Both stores' in-app purchase obligations apply to digital content and features used inside the app. Payments for physical goods and offline services are not covered, and Google Play specifies that Play's billing system must not be used for such payments (Google Play Payments policy). If the app has features that count as digital goods, such as subscriptions, passes, or point top-ups, decide at the design stage whether in-app purchase applies. The alternative payment entitlement that the App Store allows in South Korea comes with conditions, such as having to submit a separate Korea-only app binary and not being able to use it together with Apple in-app purchase in the same app (Apple: External purchase entitlement in South Korea), so if you are considering it, the conditions must be checked early in the project.
How to respond when rejected
Deciding in advance who does what on the day a rejection notice arrives shortens the time to resubmission.
- Classify the reason. Check the guideline number in the notice and determine whether you only need to fix the review information (account, description, screenshots) or have to rebuild the app. In the former case, same-day resubmission is possible.
- Reproduce it. Walk through the screens the reviewer saw under the same conditions (review account, latest OS, permissions denied). It is not uncommon for the review account to have expired or for the server to have been under maintenance during review.
- If you have questions, reply to the review team. The App Store directs you to contact the review team directly within App Store Connect. If a feature was misunderstood, send reproduction steps together with a screen recording.
- Fix and resubmit. In the review notes, state what you fixed and how, along with the guideline number. Review notes that describe new features and changes only in generic wording are themselves grounds for rejection (Guideline 2.3.1).
- If you disagree with the decision, appeal. The App Store accepts one appeal per rejection and specifies that you must respond to any request for additional information before submitting it.
- Keep a record. Document the rejection reason, the action taken, and the resubmission date. This prevents the same reason from recurring in the next version and serves as evidence for the schedule delay.
The App Store offers two paths you can use when an incident in production requires an urgent fix. One is an expedited review request. A critical bug fix or a directly related event date qualifies as a reason, and for a bug fix you must also provide steps to reproduce it on the current version. The guidelines state that abuse may lead to later requests being rejected, so use it only for real incidents. The other is a bug fix submission. Bug fixes for apps already on the store are not delayed over other guideline violations, except for legal or safety issues; if rejected, you tell the review team that you want this process applied and resolve the violation in your next submission (App Review Guidelines, App Review).
Rolling back is hard
On the web, if something goes wrong you roll back to the previous version. With an app, you cannot roll back what is already installed.
The available responses are limited.
- Submit a fixed version for review again (this takes time)
- Turn the feature off from the server (only possible if it was designed that way)
- Remove the app from the store to block new installs only (this has no effect on users who already installed it)
The second is the realistic line of defense. Building risky app features so they can be turned off by server configuration is the only means of immediate response when an incident occurs.
2. Multiple versions run at the same time
Even when you ship an update, not everyone installs it. An app in production always has a mix of versions.
The server has to deal with old versions too
If you change an API to fit the new version, the app stops working for users on old versions.
The principle is the same as in integration design.
- Adding a field is fine. Old versions simply ignore fields they do not know
- Removing a field or changing its meaning breaks old versions
- The same goes for changing the response structure
If a breaking change is necessary, you have to split the API version and keep the old version running for a period of time. That period depends on how fast users update, so you can only decide if you can see the usage share of each version. The criteria for distinguishing field additions from removals are the same as those covered in Where External System Integrations Fail — Principles of Interface Design.
The order for shipping a breaking change
On the web you deploy the server and the screens together and you are done, but with an app you have to follow an order.
- Deploy the new API first. Leave the existing path (e.g.
/v1) as it is and add a new path (e.g./v2). At this point no app is using the new path. - Submit the app that uses the new path for review. During the review period the server serves both paths.
- Roll out in phases while watching the version distribution. Check how fast the call volume on the old path is falling.
- Set an end date and notify old versions. Show a recommended-update notice first, then raise it to a required update before the end date.
- Raise the minimum supported version. Move on to the next step only after apps using the old path can no longer get in.
- Close the old path. Do not delete it right away; leave an "update required" response in place for a period of time. This is because there may still be paths that call the API without going through the minimum supported version check (background sync, widgets, push handling).
If steps 5 and 6 are swapped, users see an unexplained error screen instead of an update notice.
For this procedure to work, the server has to know the app version on every request. The simplest approach is to send version information with every request. Below is an example with arbitrarily chosen header names.
GET /v2/orders HTTP/1.1
Host: api.example.com
X-App-Platform: android
X-App-Version: 2.3.1
X-App-Build: 231
X-OS-Version: 15
If you record these headers in the access log, you can use the same data for both version distribution aggregation and incident analysis. Define the response after the old path is closed so that the app can identify it by error code. When the app receives this code, it goes to the update notice instead of a generic error screen.
{
"error": {
"code": "APP_UPDATE_REQUIRED",
"message": "Please update the app to the latest version.",
"minimumVersion": "2.3.0"
}
}
Like forced updates, handling of this error code has to be in the first version. An old app that does not know the code can only show it as a generic error.
Measure the version distribution
This is the information needed for decision-making.
- Active users per version
- Speed of migration to a new version
- Share of users at or below the minimum supported version
- OS version distribution
Without this data you cannot answer the question "when can we drop support for the old version?" The simplest structure is for the app to send version information when it connects and for the server to aggregate it.
Build forced updates into the design
There will be cases where you have to block use at or below a certain version. Security issues and changes that break server compatibility are the typical ones.
The required elements:
- The server provides the minimum supported version
- The app compares it with its own version at launch
- If it falls short, the app shows an update notice and blocks further use
- Distinguish between recommended updates (skippable) and required updates (blocking)
This feature has to go in from the first version. If you add it later, it cannot be applied to existing versions that do not have it. You end up unable to use it at the very moment you need it.
Split the version policy the server provides by OS. Because the two stores pass review at different times, if you raise the minimum supported version while only one side has the new version out, users on the other side are blocked even though there is no update for them to install. Below is an example of the response structure.
{
"android": {
"minimumVersion": "2.1.0",
"recommendedVersion": "2.3.1",
"storeUrl": "https://play.google.com/store/apps/details?id=com.example.app"
},
"ios": {
"minimumVersion": "2.1.0",
"recommendedVersion": "2.3.0",
"storeUrl": "https://apps.apple.com/app/id0000000000"
},
"maintenance": { "isActive": false, "message": "" }
}
Points that are easy to miss during implementation:
- Compare versions numerically by segment, not as strings. With string comparison,
2.10.0is judged lower than2.9.0 - Decide what happens when the policy lookup fails. If a failed lookup is treated as a block, an outage of the policy server becomes an outage of the whole app. The common approach is to keep the last received policy on the device and decide based on that value
- Check not only at launch but also when the app returns from the background. Some users do not close the app for days
- Raise the minimum supported version after the new version has been opened to all users on that store. If you raise it during a phased rollout, users who cannot see the update yet are blocked
In the Zero Salon app, the splash screen checks whether a required update applies along with the login state, and handles required and optional updates separately. This is because showing even a skippable notice as a blocking screen to a user opening the app in front of a collection machine would interrupt the flow on site.
Criteria for deciding whether to force an update
A forced update blocks users, so overusing it leads to churn. Deciding in advance which level to use for each situation saves you from debating it every time during operation.
| Situation | Action | Basis for the decision |
|---|---|---|
| Security defect related to authentication, payment, or personal information | Required update, as soon as the fixed version is released | Applied regardless of user share |
| Defect that stores data incorrectly in old versions | Block the feature on the server, then required update | For problems where damage accumulates, blocking comes first |
| Retirement of an old server API version | Recommended update, then switch to required before the end date | The point at which the share of old-version users falls below the agreed threshold |
| Screen changes required by a change in law or terms | Required update as of the effective date | Count back the review period from the effective date and submit |
| New features, design improvements | Recommended update or no notice | No reason to block |
| Errors that occur only on specific devices | Notice only for the affected conditions | Do not block everyone |
Before raising the minimum supported version, check the following.
- Have you checked the number and share of active users at or below the target version?
- Is there a new version on the store that those users can install? If the new version raised the supported OS range, users on older OS versions are blocked with no way to update
- Is the new version open to all users on both stores?
- Does the store link on the update notice screen actually work?
- Have you shared the date and time of the change and the notice wording with customer support?
If you have no choice but to block users on older OS versions, prepare a separate notice saying "This device is no longer supported" and an alternative path such as the web. A screen with only an update button is a dead end for these users.
The store's update feature is a supplementary tool
Android has the Google Play in-app updates feature, which lets users get an update from inside the app. It is supported on Android 5.0 (API level 21) and higher and offers two modes (Android Developers: In-app updates, checked October 13, 2026).
| Mode | Behavior | Suitable for |
|---|---|---|
| Flexible update | Downloads in the background while the user keeps using the app | Recommended updates |
| Immediate update | Shows a full-screen notice; the user must update and restart to continue | Required updates |
If you set the update priority (0 to 5, default 0) through the Google Play Developer API at release, the app can read this value and choose a mode. The priority can only be set when you start the release and cannot be changed later (In-app updates: Kotlin/Java).
This feature is Android-only, and it is Google Play that determines whether an update is available on the store. The policy decision that "this version and below cannot be used" still belongs to the server. Since the same policy has to apply to both operating systems, a setup where the server decides and Android uses in-app updates as the means of carrying out the notice screen is easier to manage.
Prepare server-driven configuration
These are the values you need to be able to change without releasing the app again.
- Turning features on and off
- Announcements and maintenance notices
- API server address
- External links
- Some of the wording
The wider the range you can change without a release, the easier operation becomes. However, having the app download everything from the server makes it slower and more complex, so it is better to limit this to values that actually have a chance of changing.
Apps that build their screens in JavaScript, such as React Native apps, can use OTA updates, which replace the code bundle without going through the store. In the Zero Salon app, operational content was managed on the server and OTA updates were applied alongside it, so wording fixes and simple screen changes were reflected without waiting for review.
This tool has limits under store policy. App Store Review Guideline 2.5.2 prohibits downloading and executing code that adds or changes an app's features, and Google Play prohibits downloading executable code (dex, JAR, .so) from anywhere other than Google Play, while making an exception for code that runs in an interpreter, such as JavaScript in a webview (App Review Guidelines, Google Play Device and Network Abuse policy, checked October 13, 2026). It is safer to split your operating criteria so that OTA is limited to bug fixes and adjustments to wording and screens, while feature additions that change the nature of the reviewed app go through store review. Changes that alter native code or permissions cannot be shipped by OTA on technical grounds either.
3. Devices and environments are not under your control
The web has browser differences too, but on mobile the range is wider.
Agree on the verification scope first
If this is not settled at the contract stage, disputes arise during acceptance.
| Item | What to decide |
|---|---|
| OS version | How far back to support |
| Screen size | Minimum and maximum resolution, whether tablets are supported |
| Target devices | The list of actual devices to use for acceptance |
| Network | Criteria for behavior in low-speed environments |
| Accessibility | Scope of support for enlarged text and screen readers |
Enlarged text is often left out. Quite a few users increase the text size in system settings, and screens built with fixed heights break when they do.
Things that have to be checked on real devices
These are problems a simulator does not catch.
- Hardware features such as camera, location, and biometric authentication
- Receiving push notifications
- Payment flows
- Performance on low-end devices
- Battery consumption
- Conflicts with the screen notch and the bottom gesture area
It is better to draw up the list of real devices and a plan for renting or buying them early in the project.
Define the offline state
Apps used on the move lose their network connection all the time. It happens far more often than on the web.
What to decide for each screen:
- View screens — Show cached content or an empty screen? If you show it, indicate when the data was received
- Input screens — Save drafts so that content being written is not lost
- Send failures — Retry, or leave it to the user?
- Recovery — Retry automatically when the network comes back?
Losing content you were in the middle of writing is the worst experience from the user's point of view. If there is a long input form, local draft saving is close to mandatory.
If you store data on the device, you also have to decide what to store. Leaving personal information or credentials in plain text becomes a problem if the device is lost. Sensitive values should use the secure storage provided by the OS, and a procedure to clear them at logout is needed.
Manage app size and first-launch time
If the install size is large, some users give up on the download itself. This is especially true on mobile networks.
- Decide whether to bundle all resources such as images and fonts in the app or download them later
- Remove libraries that are not used
- Decide what screen to show on first launch. A white screen lasting several seconds is taken as a malfunction
Background behavior is restricted
What an app can do when it is not on screen is controlled by the OS. Designing with a web-service mindset leads to mismatches.
- Tasks that run periodically in the background are not guaranteed
- Behavior varies with battery optimization settings
- Scheduled tasks may disappear when the app is terminated
If periodic sync or location tracking is in the requirements, you have to check how far it is actually possible and align expectations. This is an area where it is hard to promise "it always works."
4. Push notifications are more complex than they look
They look simple, but there are many design elements.
Decide when to request permission
If you request it right after install, the denial rate is high. Once denied, you cannot ask again, and the user has to turn it on in settings.
- Showing a screen first that explains why notifications are needed
- Requesting at the point where notifications actually become useful
- A path for guiding users who denied it later on
Delivery is not guaranteed
Push is not a reliable means of delivery.
- If the device is off or has no network, notifications are delayed or lost
- The user may have turned notifications off
- The OS may delay them depending on battery state
Do not rely on push alone for important content. A safe setup is to have a notification inbox that can also be checked inside the app, and to use SMS or email in parallel for what is truly important.
Tokens have to be managed
A token is issued for each device, and it changes.
- It changes when the app is reinstalled or its data is cleared
- If you do not clean up the token at logout, notifications go to someone else
- One user may use several devices
- Tokens that have not been used for a long time need to be cleaned up
Failing to clean up the token at logout leads to real incidents. The person who takes over the device receives the previous user's notifications.
Decide where a tap leads
If tapping a notification only opens the app's first screen, the user has to find the content again. You need a structure that specifies the destination screen for each notification.
What to decide:
- The destination screen and required values for each notification type
- Handling when it is tapped while not logged in
- When it is tapped after the app has been deleted (send the user to the store?)
- How to guide the user if they have no permission for the content
The same structure is used when the app is opened from an external link. This is the flow where tapping a link in a text message or web page takes the user into a specific screen of the app. You need branching that sends the user to the app if it is installed and to the web or the store if it is not, and this setup requires work on the server and domain side as well.
It is a feature often required by marketing and customer support, so even when it is not stated in the requirements, the request frequently comes in later. It is better to confirm the scope early.
Control the sending volume
If notifications are frequent, users turn them off. Once turned off, it is hard to reverse.
- Split receiving preferences by type
- Restrict sending late at night
- Do not send the same content repeatedly
- Have a procedure to check the number of recipients before sending
The characteristics of each channel, send timing, and the management of receiving preferences and consent are covered in detail in The Point Where Notifications Start Getting Ignored — Designing a Delivery System.
5. You need to know about problems before users do
On the web you can understand what is happening from server logs. An app is code running on the user's device, so that does not hold. When the app crashes, the server does not know.
Put an error collection tool in from the start
You need a mechanism that gathers information when the app terminates abnormally or an exception occurs. The information to collect:
- Where it occurred and the call flow
- App version and OS version
- Device model
- Frequency and number of affected users
- Which screen the user was on just before
This tool has to go in before launch. If you attach it after a problem occurs, you will never know what is happening to the users on that version.
Making sure personal information is not collected along with it is also something to check. Input values or tokens sometimes get mixed into the error information that is uploaded.
Decide what counts as a serious problem
You cannot respond to every error. You need criteria.
| Level | Example | Response |
|---|---|---|
| Urgent | Crash on launch, payment failure | Release a fix immediately or block the feature on the server |
| High | A main feature does not work | Include in the next release |
| Medium | Occurs only under specific conditions | Handle according to priority |
| Low | Display issues | Handle in batches |
Managing the crash rate as a metric makes decisions easier. You need to know the normal level to be able to tell whether it got worse after a new version was released.
There are official figures you can refer to when setting a baseline. Google Play states that in Android vitals, if the user-perceived crash rate exceeds 1.09% overall across all devices or 8% for a single phone model, it may reduce the app's visibility on the store or show a warning on the store listing. The calculation uses data from the last 28 days (Android vitals, checked October 13, 2026). These values are the line at which the store starts applying penalties, so your internal response threshold should be set lower. It is also worth noting that there is a separate per-model threshold. Even if the overall average is healthy, an app that crashes heavily on a particular model is penalized on that model.
Roll out in phases
If you ship a new version to all users at once, the impact is at its maximum when there is a problem.
- Release to some users first and check the metrics
- If nothing is wrong, raise the percentage
- If a problem is found, halt the rollout
Users who already received it cannot be rolled back, but you can stop it from spreading further. Use the phased rollout feature the store provides, or open new features gradually through server configuration.
Phased rollout behaves differently on the two stores (checked October 13, 2026).
| Item | App Store phased release | Google Play staged rollout |
|---|---|---|
| Target | Version updates. A random sample of users who have automatic updates turned on | App updates only. Cannot be used for the initial release |
| Percentage | Fixed at 1% → 2% → 5% → 10% → 20% → 50% → 100% over 7 days | You set the percentage at release and raise it yourself |
| Halting | Can be paused. Up to 30 days in total, with no limit on the number of pauses | When halted, it is not distributed to additional users. Can be resumed if nothing is wrong |
| Users who already received it | Stay as they are | Stay as they are |
| Bypass path | Anyone can get it manually from the store even during a phased release | The official documentation does not mention a manual install path |
| When a problem is found | Pause, then submit a fixed version | Halt, then create a new release with the fixed bundle and roll it out |
(App Store Connect Help: Release a version update in phases, Play Console Help: Staged rollouts)
There are three points to build into your operating procedures.
- An App Store phased release does not block exposure. Users who tap update directly in the store get the new version from day one. You cannot treat a version that is incompatible with the server as "fine because only 1% got it"
- Google Play does not allow a staged rollout for the first release. The risk of the first release has to be reduced during the closed and open testing stages
- Neither is a rollback feature. Halting only stops the spread; to rescue users who already received it, you have to ship a fixed version or turn the feature off on the server
Decide the metrics to look at before raising the percentage and the criteria for halting before the release. These should be statements that can be judged by numbers, for example "halt if the new version's crash rate is clearly higher than the previous version's" or "halt if the payment or login failure rate goes outside the normal range," and you should also decide who makes the call to halt. Metrics fluctuate at the early percentages where the sample is small, so set the interval between percentage increases to the time it takes to gather the number of users needed to make a judgment.
Provide a channel for user inquiries
Having a way to send inquiries inside the app speeds up problem identification. If the app version, OS version, and device information are sent along automatically, the time needed to check drops considerably. The back-and-forth of asking the user "which model are you using?" disappears.
Store reviews are another channel to check. However, by the time a problem shows up in reviews, many users have often already experienced it.
6. Store policies and accounts are project assets
This is outside the technical side, but it frequently affects the schedule.
Sort out accounts and permissions first
- As a rule, the store developer account should be created in the client's name. If the app is published under the vendor's account, transferring it later is cumbersome
- Creating the account and verifying the business take time
- You have to decide who keeps the certificates and keys
- Decide who gets access to the account
Account preparation takes time regardless of development, so it has to start in the first week of the project. These are the requirements that affect the schedule (checked October 13, 2026).
| Item | Requirement | What it means for the schedule |
|---|---|---|
| Apple Developer Program enrollment as an organization | Must be a legal entity that can enter into contracts and needs a D-U-N-S Number (government organizations excepted). The person enrolling must have the legal authority to bind the organization. A website on the organization's domain and a work email are required. USD 99 per year | The client has to decide internally who will enroll and how authority is delegated first |
| Google Play organization account | A D-U-N-S number is required. Issuing one can take up to 30 days. The legal name and address in the payments profile must match the D-U-N-S information | Checking whether a D-U-N-S number already exists is the very first thing to do |
| New Google Play personal account | Personal accounts created after November 13, 2023 must complete a closed test with at least 12 testers opted in for at least 14 consecutive days before applying for a production release | If releasing under an individual's name, at least 2 weeks plus the time to recruit testers are added |
(Apple Developer Program enrollment, Play Console Help: Required information to create an account, Play Console Help: App testing requirements for new personal developer accounts)
If the client is a corporation, enrolling as an organization account is the right choice, and in that case the closed testing requirement does not apply. However, an account created earlier in the representative's personal name does fall under this requirement, so if there is an existing account, its type and creation date must be checked.
Record ownership of accounts, certificates, and keys in a table
Whether you can keep releasing the app when the vendor changes or the person in charge leaves depends on whether this table exists. Fill in the items below and include it in the handover deliverables.
| Asset | Owner | What to decide | Impact if lost or expired |
|---|---|---|---|
| Apple Developer account (Account Holder) | Client | Use an organizational address rather than a personal one for the account email; who manages the two-factor authentication device | Submission and permission management are blocked while the account cannot be accessed |
| App Store Connect user permissions | Granted by the client | The roles to give vendor staff and when to revoke them | Accounts of people who have left become a security problem if they remain |
| iOS distribution certificate | Client's team | Who can create it (Account Holder, Admin), where the private key is kept | Existing apps on the store are not affected even if it expires or is revoked. New builds signed with that certificate cannot be uploaded |
| APNs certificate or key | Client's team | The value registered on the sending server and who is responsible for renewal | Push cannot be sent if the certificate expires or is revoked |
| Google Play developer account | Client | Owner account, per-user permissions | The account may be restricted if a mismatch in corporate information is not resolved |
| Android app signing key | Held by Google when Play App Signing is used | Whether to use Play App Signing | Cannot be reset if self-managed and lost |
| Android upload key | Client (the vendor may hold it in custody) | Where the keystore file and password are kept, who has access | A reset can be requested in Play Console if lost or leaked |
| Service accounts for push, analytics, and error collection | Client | Project owner, payment method | If tied to the vendor's account, data continuity may be broken on transfer |
| Domain, app link configuration files | Client | Domain administrator, who deploys the configuration files | If the domain expires, deep links and the privacy policy link break together |
| Source repository, build configuration, environment variables | As per the contract | Repository permissions, how secrets are handed over | The build cannot be reproduced |
(Apple: Certificates, Play Console Help: Play App Signing, checked October 13, 2026)
Two kinds of Android signing keys have to be distinguished. With Play App Signing, Google holds the app signing key that signs the app delivered to users, and the development side signs uploads with an upload key. If the upload key is lost or leaked, you can create a new key and request a reset in Play Console. In contrast, if you manage the app signing key yourself without Play App Signing and lose it, there is no way to reset it. This is the case in which you can no longer continue updating the same app. When taking over an app in production, check which approach is in use first, and include the key storage method and backups in the project deliverables.
Exchanging keystore files and passwords or certificate private keys over messengers or email should be avoided. Keep them in a secrets management tool, and note in the table above who can access them.
Moving an app already released under the vendor's account to the client's account is possible on both stores. However, some things do not carry over as they are.
- App Store: Ratings, reviews, and the bundle ID are retained and users continue to receive updates. Before the transfer, all TestFlight builds and testers have to be removed, the transferor loses access to app analytics data, and the Apple Pay merchant ID does not transfer (App Store Connect Help: App transfer)
- Google Play: Users, statistics, ratings and reviews, and subscriptions transfer. Orders placed before the transfer remain with the original account and refunds have to be processed there, closed testing groups have to be recreated, and settings for integrated services such as analytics and push have to be set up again in the new account (Play Console Help: App transfer)
The more payments or subscriptions an app has, the bigger the transfer work becomes. This is why we advise releasing under the client's account from the start.
Leave room to respond to policy changes
Store policies change. Requirements such as how collected personal data is disclosed, use of the advertising identifier, and providing an account deletion feature have been added over time.
- Designate a person to receive policy change announcements
- Reflect requirements with a compliance deadline in the schedule
- State the scope of policy response in the maintenance contract
The last item is important in practice. When a policy changes during operation and a modification is needed, a dispute arises over whether it is defect repair or additional development. It is better to draw the line at the contract stage. How to separate scope in documents is covered separately in How Scope Grows in SI Projects and How to Design Change Management to Contain It.
Key requirements in force now
The following is what we confirmed in each official document on October 13, 2026. Store policies change after advance notice, so the original text must be checked again before submission.
| Area | App Store | Google Play |
|---|---|---|
| Build tools and target version | From April 28, 2026, uploads must be built with Xcode 26 or later and a 26-series SDK such as iOS 26 | From August 31, 2026, new apps and updates must target Android 16 (API level 36) or higher to be submitted. An extension can be requested until November 1, 2026 |
| Existing apps | - | Apps that do not target Android 15 (API level 35) or higher are not shown to new users on Android versions higher than the target level |
| Account deletion | Apps that support account creation must let users initiate deletion within the app. Offering only deactivation is insufficient. A customer support process such as phone or email cannot be required (highly regulated industries excepted) | Along with an in-app deletion path, a web link must be provided through which deletion can be requested without reinstalling the app |
| Disclosure of collected data | Privacy practices are entered in App Store Connect when submitting new apps and updates | Completing the Data safety form is mandatory except for apps in internal testing only. It must be completed even if no data is collected |
| Third-party SDKs | Using required reason APIs requires declaring approved reasons in the privacy manifest in order to upload (from May 1, 2024, including SDK code). When newly adding an SDK designated by Apple, that SDK's manifest and signature are required | The developer is also responsible for reflecting the data that SDKs collect and share in the form |
| Tracking and advertising identifier | On iOS 14.5 and later, App Tracking Transparency (ATT) permission is required to track users or access the advertising identifier. Before permission is granted, the identifier value is all zeros | - |
The sources are Apple: Upcoming Requirements, Google Play target API level requirements, Apple: Offering account deletion in your app, Google Play account deletion requirements, Apple: User privacy and data use, Google Play Data safety section, and Apple: Third-party SDK requirements.
Let us go through the parts that affect design and schedule.
Account deletion does not end with a single screen. When a deletion request is received, the data linked to the account has to actually be deleted, and if there is data that must be retained by law, users have to be told what is retained and for how long. According to Apple's guidance, users with auto-renewable subscriptions have to be informed that billing continues through Apple, apps that use Sign in with Apple have to revoke tokens on deletion, and guest accounts created automatically without a sign-up process are also subject to deletion. In the ad reward app we built, account deletion requests are handled on a separate screen of the admin console so that requests and their outcomes remain on record. This is because a service where money is involved, such as points and withdrawals, has things to settle before deletion, so the state between receiving a request and processing it has to be managed.
Disclosure of collected data has to match actual behavior. Google Play places responsibility for the accuracy of the disclosure on the developer and states that it may block updates or remove the app if a discrepancy is confirmed. Data sent by analytics, advertising, and error collection SDKs is included, so a procedure to recheck the disclosure every time an SDK is added or its version is raised is needed. Also check that the content in three places, the privacy policy, the store disclosure, and the permission request wording, does not contradict each other.
Cross-platform is no exception. Apple's list of designated SDKs includes Flutter and many Flutter plugins, the Firebase family of SDKs, and Hermes, the JavaScript engine used by React Native. If framework and plugin versions are old, the manifest may be missing, so check dependency versions during development, not just before submission.
Target version increases come every year. Google Play raised the requirement to API level 35 on August 31, 2025 and to 36 on August 31, 2026, and Apple also raised the minimum Xcode version required for upload in 2023, 2024, and April 2026. Raising the target API level can change the default behavior of permissions, background execution, and how screens are displayed, so in many cases the work does not end with changing the build settings. It has to go into the estimate as work that includes regression testing of all features.
Keep review information as a deliverable
- App description, screenshots, keywords
- Answers to the age rating questionnaire
- Privacy policy link
- Review account information
- Contact information for inquiries
If this is not organized, it gets recreated every time the person in charge changes.
7. Frequently asked questions
Should we choose native or cross-platform?
The criteria for deciding:
| Condition | Suitable choice |
|---|---|
| Heavy use of hardware features | Native |
| Mostly screens, with the same behavior on both operating systems | Cross-platform |
| Releasing on one OS first | Either works |
| Securing staff for long-term maintenance | Whichever fits the team's capabilities |
Even if you choose cross-platform, areas that behave differently per OS remain. Push, permissions, payment, and background behavior are the typical ones. The expectation that "build it once and both sides are done" does not hold.
Can't we just build it as a webview?
Building parts of the app as webviews is common. Terms of service, announcements, and frequently changing content are the typical cases. Being able to modify them without a release is a big advantage.
However, an app that as a whole merely wraps a website can run into problems in review. What the stores require is value as an app. App Store Review Guideline 4.2 says that an app must have features, content, and UI that go beyond a repackaged website (App Review Guidelines). If the setup has no native features at all, it needs to be examined in advance.
A setup with the web as the main body is not impossible in itself. The ad reward app was built with its core features implemented on the web and the app wrapping them, while push notifications, integration with payment apps, external browser handling for social login, and the deep link return were handled in the app layer. Social login and payment sometimes do not work as they are inside a webview, so these flows at least had to be taken on by the app. Separate what can be done on the web from what has to be an app first, and you should also be able to explain in the review notes what the app is responsible for.
Does building the app and the web at the same time reduce cost?
The server and API are shared, so that part is reduced. The screens generally have to be built separately for each.
Points to note when running them together:
- Both clients use the same API, so the impact of a change doubles
- The parts where the screen flow differs have to be decided early
- Release cycles differ. The web is immediate; the app goes through review
If you do not account for the difference in release cycles, you end up in a situation where the server has been changed but the app alone is waiting in review and does not work. It is safer to design server changes so that they are switched on after the app release is complete.
How is acceptance testing carried out?
The difference is that you cannot share a URL for checking as you can on the web. A distribution path for acceptance has to be set up first.
- Use an internal distribution channel that does not go through the store
- Testers have to be told how to install it. For staff who are not comfortable with technology, this process itself becomes a barrier
- Check whether a reinstall is needed each time the version goes up or whether it updates automatically
- Set up the form so that acceptance feedback includes the app version and device information
Without the last item, all you accumulate is feedback saying "it doesn't work." If you do not know which version and which device it happened on, you cannot reproduce it.
It is also better to allow more slack for the acceptance period than on the web. This is because distribution time is added every time something is fixed and checked again.
How much maintenance is needed after launch?
An app left unattended stops working.
- Behavior has to be checked with every major OS update
- The minimum target version required by the stores goes up periodically
- Support for libraries in use ends
- Certificates and keys expire
It is realistic to assume that an update release is needed once or twice a year even with no feature changes. You should check whether this work is included in the maintenance contract.
What actually happens when an app is left unattended differs by store. On Google Play, existing apps whose target API level is below the requirement stop being visible to new users on the latest Android devices. On the App Store, existing apps remain, but unless you build with the required Xcode version you cannot upload even an urgent bug fix (see the requirements table in Section 6). To avoid a situation where you have to upgrade the build environment first when an incident occurs, it is better to schedule regular updates in line with the timing of store requirement changes.
8. Pre-kickoff checklist
Schedule
- Have you reflected review time and the possibility of rejection in the schedule?
- Do you have a plan to demo through an internal distribution channel?
- Have you reserved time for account creation and business verification?
Version management
- Is the forced update feature included in the first version?
- Does the server provide the minimum supported version?
- Do you aggregate the user distribution by version?
- Is there a backward compatibility policy for API changes?
- Can features be turned off by server configuration?
Environment
- Are the supported OS versions and device range agreed?
- Is there a list of real devices to check and a plan for obtaining them?
- Do screens stay intact when text is enlarged?
- Have you checked the feasibility of the background behavior requirements?
Push
- Have you designed the timing of the permission request and the advance explanation?
- Is there an in-app notification inbox?
- Are tokens cleaned up at logout?
- Are there per-type receiving preferences and restrictions on sending times?
Accounts and policy
- Are the store accounts in the client's name?
- Are the storage and backup methods for signing keys decided?
- Is the review information kept as a document?
- Is policy change response stated in the maintenance scope?
- Have you checked whether a D-U-N-S number exists and the account type (organization or personal)?
- Have you filled in the ownership table for accounts, certificates, and keys?
9. Pre-submission checklist for the stores
Where the pre-kickoff list is about design, this list is what you check before pressing the submit button. Use it again for every version.
Review information
- Does login actually work with the review account? If the app requires identity verification or SMS verification, have you arranged a way for the reviewer to get through?
- Will the server be up throughout the review period, with no overlap with a maintenance window?
- Have you described this version's changes and how to verify them specifically in the review notes?
- For features that can only be verified with a specific device or equipment, have you prepared a demo video?
- Do the screenshots and app description match the actual screens?
App state
- Are there no "coming soon" screens, non-working buttons, or test wording left?
- Do all links in the app open? This includes the customer support link and the privacy policy link
- Have you run it on a real device with the latest OS version?
- With all permissions denied, does the app stay running and show guidance?
- Does the permission request wording explain specifically what the permission is used for?
Privacy and policy
- If the app allows sign-up, can account deletion be initiated within the app?
- Have you registered the web link for account deletion requests on Google Play?
- Is the store's disclosure of collected data correct for the SDKs included in this version?
- Do the privacy policy, the store disclosure, and the permission wording agree with each other?
- Do the age rating questionnaire answers match the current content?
- If there are payments for digital goods, have you determined whether in-app purchase applies?
Build and release
- Does the build meet the build tools and target version the stores require?
- Have you raised the version name and build number?
- Did you build with the production server address and production keys?
- Does the error collection tool work in this build?
- Is the server API this version uses already deployed to production?
- Have you decided whether to use a phased rollout, the criteria for halting, and who decides to halt?
- If you plan to raise the minimum supported version after release, have you decided when?
Closing
The hard part of an app project is not building the screens. It is designing on the premise that a fix does not take effect right away.
Once you accept this premise, the mechanisms you need become clear. Put forced updates in the first version, make risky features switchable from the server, change APIs in a way that stays compatible with old versions, and measure the version distribution. None of these is a big job on its own, but without them there is nothing you can do when an incident occurs.
We have built mobile apps integrated with the web and native apps for on-site terminals many times. If you are preparing an app project, feel free to get in touch.
Related articles
- Where External System Integrations Fail — Principles of Interface Design
- The Point Where Notifications Start Getting Ignored — Designing a Delivery System
- How Scope Grows in SI Projects and How to Design Change Management to Contain It
References
Store policies and figures are as checked on October 13, 2026. Policies change after advance notice, so please check the original text again before submission.
- App Review Guidelines (revision of June 8, 2026) — Apple Developer
- App Review — Apple Developer
- Upcoming Requirements — Apple Developer
- Offering account deletion in your app — Apple Developer
- User privacy and data use — Apple Developer
- Upcoming third-party SDK requirements — Apple Developer
- Distributing apps using a third-party payment provider in South Korea — Apple Developer
- Release a version update in phases — App Store Connect Help
- TestFlight overview — App Store Connect Help
- Overview of app transfer — App Store Connect Help
- Certificates — Apple Developer
- Apple Developer Program enrollment requirements (in Korean) — Apple Developer
- Target API level requirements (in Korean) — Play Console Help
- App testing requirements for new personal developer accounts (in Korean) — Play Console Help
- Required information to create a developer account (in Korean) — Play Console Help
- App publishing and review status (in Korean) — Play Console Help
- Set up internal, closed, and open testing (in Korean) — Play Console Help
- Staged rollouts (in Korean) — Play Console Help
- Play App Signing (in Korean) — Play Console Help
- Transfer apps to a different developer account (in Korean) — Play Console Help
- Account deletion requirements (in Korean) — Play Console Help
- Data safety section (in Korean) — Play Console Help
- Payments policy (in Korean) — Play Console Help
- Device and Network Abuse policy (in Korean) — Play Console Help
- In-app updates — Android Developers
- Support in-app updates (Kotlin or Java) — Android Developers
- Android vitals — Android Developers

