Publish an App Built With AI to the App Store
Most AI builders make web apps, not mobile apps. How to work out what you actually built, pick the right route, and get listed on both stores.

Search for a command to run...
Most AI builders make web apps, not mobile apps. How to work out what you actually built, pick the right route, and get listed on both stores.

No comments yet. Be the first to comment.
A Base44 app can fail upload on an invalid URL scheme derived from its name. What the error means and how to set a valid scheme without renaming.

Your Lovable app fails upload with an invalid URL scheme error. Why the project name causes it, and how to set a valid scheme without renaming.

Your build fails with an invalid URL scheme before review ever sees it. What ITMS-90158 means, what triggers it, and how to fix it in a minute.

Base44 packages your app for the stores. What its own docs list as unsupported, and how to add push, offline and billing when your app needs them.

Despia Blog: Build Native iOS & Android Apps from Web Code
120 posts
Publishing an app built with AI is two problems, and the second one wastes more time than the first. The first is that most AI builders produce a web app that lives at a URL, and the App Store does not accept URLs. The second is that people do not know which of those two things they are holding, so they follow advice written for the other one and nothing works.
Identify what your tool produced before you do anything else. Everything after that follows from it.
Lovable, v0 and Base44 produce web apps. Base44 now packages that web app for the stores itself, but the thing inside the wrapper is still a web app. Claude Code, Cursor and Codex give you whatever you asked for, which is usually a web app you own outright.
Bolt and Replit are the ones people get wrong, and a lot of writing about them is stale. Both can scaffold Expo and React Native projects, with the store binary built in the cloud through Expo EAS rather than in the browser. If that is what you have, you are already on the rebuild route and this is not your guide.
Glide, Softr, Wix and Webflow on its own are a separate case, covered next.
This is the question that decides whether any of this works, and almost nobody asks it first.
Every native capability, on every route that packages a web app, works by calling a JavaScript function from your own code. Push notifications, biometrics, native billing, the camera. If you cannot put JavaScript into your app, none of it is reachable, and an app with no native capability is exactly the one Apple rejects.
If you are on a builder with no code access, you have two honest options. Ship a Progressive Web App and accept that Apple will not list it, or rebuild in something that gives you the code. Saying that costs a sale sometimes. Paying for a runtime you cannot reach costs more.
| Route | App Store | Second codebase | Needs a Mac | Updates |
|---|---|---|---|---|
| Progressive Web App | No | No | No | Instant |
| Capacitor, self-managed | Yes | The native project | Yes | No default answer |
| React Native rebuild | Yes | Yes, permanently | No | Native changes need review |
| Despia | Yes | No | No | Whole UI over the air |
A PWA is the cheapest and does not answer the question. Android will list one as a Trusted Web Activity. Apple lists no PWAs at all.
Capacitor is the do-it-yourself version of packaging. You own a real native project, which means you own the Mac, Xcode, code signing, a plugin for push, no billing, and an offline mode that serves from file:// where Supabase auth and OAuth redirects fail. Ionic has begun winding down Appflow, so over-the-air updates have no default answer there either. It is free and open source, and if your time is worth less than a licence it is the honest pick.
A React Native rebuild gives you genuinely native views and is right for animation-heavy, gesture-heavy or 3D products. It is a frontend rewrite you then maintain forever.
Despia ships the web app you already have as a signed binary for both stores, with 50+ native device features reachable from your existing JavaScript through a single function. One codebase, which is still your website, web updates over the air with no resubmission, and full Xcode and Android Studio export whenever you want it.
Search this and you will find pages arguing that packaged web apps are second-rate, mostly run by tools selling a rebuild. Check it instead of arguing about it.
Open Canva on an iPhone, tap 3 or 4 times quickly on an ordinary part of the interface, hold the last tap and drag.
The text-selection magnifier appears over a tile label. That label is not a text field and not an input, it is ordinary interface chrome. Native labels are not selectable, so pressing and holding one does nothing at all. Web text is selectable by default, which is why the loupe shows up. The test is iOS only, since it is a WebKit behaviour and Android's WebView does not produce the same magnifier.
Canva does not leave it to inference either. Its technical requirements list Android System WebView 89 or higher as a requirement of the app, and Chrome does not use System WebView, so that line is about the app rather than about browsing Canva in a browser.
Run the same test on the Lovable app and it happens over the header.
Run it on the Base44 app and it happens over the greeting on the home screen.
Both of the AI builders you are being told to rebuild away from render their own mobile interfaces as web content. Shopify's engineering team published the same decision in April 2025, describing WebViews as central to their mobile strategy across roughly 600 screens while keeping native and React Native for the handful of features that need it.
None of those companies is short of engineers. Where the web platform genuinely loses is custom gesture recognizers, frame-by-frame game loops and heavy 3D, and if that is your product you should rebuild it.
Three guidelines account for nearly everything that happens to this audience.
Guideline 4.2 is minimum functionality, and it catches packaged web apps with nothing added. The fix is 2 or 3 real native behaviours on paths a reviewer will walk.
Guideline 4.3 is spam, and it is getting more relevant. Apple rejects batches of near-identical apps, and AI builders make near-identical apps easy to produce. If yours is one of several similar submissions, expect more scrutiny rather than less.
Guideline 3.1.1 is in-app purchase. Digital content requires Apple's own billing, so a Stripe checkout inside the app is the single most common rejection for converted web apps. Physical goods and real-world services are fine on Stripe.
If your app pipes user content to a model API, there is also a requirement for explicit consent before personal data goes to a third-party AI, and collecting that consent is on you.
Every one of these tools defaults to a web layout, because it was trained on websites. Left alone it produces something that reads as a website on a phone, and this is the cheapest thing to fix now and the most expensive to retrofit.
Move primary navigation to a bottom tab bar, since a top nav or a hamburger tells anyone holding a phone they are on a website. Pad against the device insets so content clears the notch and the home indicator, with a fallback so the same CSS keeps working in a browser.
.tab-bar { padding-bottom: calc(12px + var(--safe-area-bottom, 0px)); }
Then drop the mouse-only patterns: hover states carrying meaning, tiny close targets, horizontal scrolling. Test on your actual phone, not a narrow desktop window.
Point your agent at the real API first, or it will invent one. The MCP address is the same everywhere: https://setup.despia.com/mcp. In Lovable that goes under Connectors, Chat connectors, New MCP server, with Authentication set to No authentication, because Lovable defaults that field to OAuth and the default is what makes it fail silently. In Base44 it is your profile, Settings, MCP connections, Add custom MCP, Authentication left as Not required. In Cursor it is ~/.cursor/mcp.json, in VS Code .vscode/mcp.json with the top-level key servers instead of mcpServers. Ask your agent to list the haptic schemes afterwards and you should get 5 real ones back.
Then install despia-native and gate every call on the environment check, because the same code still runs in a browser.
import despia from 'despia-native'
const isDespia = navigator.userAgent.toLowerCase().includes('despia')
export function completeAction(id) {
markDone(id)
if (isDespia) despia('successhaptic://')
}
Storage Vault is worth learning early, because it solves the problem AI-built apps hit first: giving a user an identity without a signup wall. It is encrypted storage backed by iCloud Key Value Store and Android Backup, so the value survives reinstall and travels with the store account that owns their purchases. Generate the id yourself rather than reading a hardware identifier, which is what Apple's fingerprinting rules exist to stop.
// readvault throws when the key does not exist, so the catch is first launch
let deviceId
try {
const data = await despia('readvault://?key=deviceId', ['deviceId'])
deviceId = data.deviceId
} catch {}
if (!deviceId) {
deviceId = crypto.randomUUID()
await despia(`setvault://?key=deviceId&value=${deviceId}&locked=false`)
}
That one id can be the account key in your database, the RevenueCat external id and the push external user ID.
Point the app at a domain you own before you build anything. The URL is compiled into the binary and is the one thing an over-the-air update cannot change, so shipping on a builder subdomain and moving hosts later means a new binary and a new review.
A reviewer who cannot sign in rejects the app as incomplete. Put working credentials in App Review Information and use a password account, not a magic link they cannot receive. On Google Play the same credentials go in App access and Google reuses them on every future review, so they have to keep working.
Generic purpose strings get auto-rejected under Guideline 5.1.1. A privacy policy behind a login or on a temporary preview host fails too. And if users can create an account, they must be able to delete it from inside the app.
If your Play account is a personal account created after 13 November 2023, you need 12 testers opted in for 14 continuous days before applying for production. Internal testing does not count and the requirement is per app.
Friends are the free route if you can reach 12. Beyond that, Testers Community runs a free app where developers test each other's projects to earn credits, and sells a done-for-you version from around $15. We have no affiliation and get nothing if you use it. Judge any service on whether written feedback comes back, because Google's production application asks what feedback you received and what you changed because of it.
Ship the AAB to closed testing on day 1 to start the clock rather than waiting it out. On any route that loads your live URL, web changes reach testers with no new build and no reset. Apple has no equivalent rule, so submit there in parallel.
The app you already built, listed on both stores under your own developer accounts, with real device capability behind it. On any route that loads your live URL, redeploying reaches installed apps on next launch with no review queue, and only the native layer needs a new binary.
Take the app you just built and ship it to iOS and Android without a CLI or a Mac. Code signing and submission run from the browser.