Skip to content
    Field notes

    App Store rejection reasons a Flutter shell can actually prevent

    The App Store rejections that hit the shell, not the idea: Sign in with Apple, account deletion, in-app purchase, crashes. How a ShipAppFast Flutter boilerplate cuts them, and what it cannot fix.

    7 min read

    Most first-submission rejections are not about your idea. They are about a shell that is missing Sign in with Apple, account deletion, a real purchase restore, or a build that crashes on a reviewer’s phone. ShipAppFast is that shell, already built, so those tickets are less of the review.

    The short answer

    Apple rejects incomplete, misleading, or non-compliant binaries. A production Flutter boilerplate cannot make a thin idea pass Guideline 4.2, and it cannot write your privacy policy. It can remove the cluster of rejections that come from rebuilding auth and payments under deadline: Guideline 4.8, Guideline 5.1.1(v), Guideline 3.1.1, and the crash-on-launch slice of Guideline 2.1.

    ShipAppFast ships email, Google, and Apple sign-in, in-app account deletion, RevenueCat and Superwall, push, crash reporting, and a project that runs before you have keys. You still submit a unique product, a demo account, and metadata that matches the binary. The click-by-click list is the Flutter App Store submission checklist. This post is why those items exist.

    The rejections that are about the shell

    Review has two piles. One pile is your product: is it useful, is it distinct, does the description match. The other pile is hygiene the reviewer has seen a thousand times. Founders lose a week on the second pile because they built the first pile on top of a login screen the model invented on a Tuesday.

    These are the hygiene tickets a finished shell is meant to shrink. None of them is a guarantee of approval. A missing button, a purpose string you rewrote into nonsense, or a paywall you pointed at Stripe will still fail.

    Guideline 4.8 — Google sign-in without a private option

    If the app offers a third-party login such as Google for the primary account, Apple expects a privacy-focused equivalent. Sign in with Apple satisfies it. Apps that use only their own email system are outside this rule. Apps that ship Google alone are not.

    The usual Flutter failure is a Google button the agent added because the tutorial had one, and no Apple button beside it. ShipAppFast already has email, Google, and Apple sign-in in the same account flow, plus one-time codes, phone verification, and password reset. You brand the screen. You do not spend the review cycle discovering Guideline 4.8.

    You still have to turn the capability on in the Apple developer account and ship the entitlement in the build you upload. The kit is the client flow, not a substitute for the checkbox in the portal.

    Guideline 5.1.1(v) — no account deletion

    If people can create an account, they must be able to start deletion inside the app. Deactivation is not deletion. A “email us to delete” link is how this ticket is born. Apple has required the in-app path since June 2022. The deletion control has to be findable, typically in account settings, and it has to lead to the account record and the personal data tied to it actually being removed.

    ShipAppFast includes profiles and account deletion in the shell, so the screen exists before you invent a settings page at midnight. Two details stay on you, because they depend on your backend.

    If you offered Sign in with Apple, deletion should revoke the token through Apple’s revoke endpoint. Confirm that call is wired for your project before you submit. And if the user has an auto-renewable subscription, tell them billing continues with Apple until they cancel. Deleting the account does not cancel the subscription. Apple’s own note on offering account deletion is the source for both.

    Guideline 3.1.1 — digital goods paid for outside the app

    Digital features, subscriptions, and content unlocks have to go through in-app purchase. A Stripe checkout for the pro tier is the classic reject. Physical goods and certain reader or multiplatform exceptions exist. A normal consumer app is not one of them.

    The shell uses RevenueCat for entitlements and Superwall for the paywall, which is the path that talks to StoreKit and Play Billing instead of a web checkout. Restore purchases has to be visible. Reviewers look for it. How those two tools split the job is in RevenueCat vs Superwall, and the wiring notes are in Flutter subscriptions without the rewrite.

    Pointing Superwall at an external checkout for a digital unlock puts the rejection back. The kit cannot save a paywall you deliberately aim at the wrong pipe.

    Guideline 2.1 — crashes, placeholders, and a build nobody can log into

    Performance rejections in 2.1 are often boring. The binary crashes on launch. A button does nothing. The reviewer cannot get past login because the demo account was never created, or the account has no data. Placeholder copy and “lorem” settings screens get read as incomplete.

    A pinned toolchain and a project that already builds on both platforms removes one cause: the first-week Gradle and CocoaPods failures that become a crash only on the archive you uploaded. Sentry and Crashlytics are in the kit so you see the launch crash before the reviewer does. Mock data means the app is usable before the backend exists, which is how you notice a dead button on your own phone.

    The demo account is still your job. If login gates the app, App Store Connect needs a working username, password, and enough data that the reviewer is not staring at an empty list. Write that in the review notes. A shell with real auth makes the account possible. It does not create it for you.

    What the boilerplate does not get you past

    Guideline 4.2, minimum functionality. Apple wants an app, not a website in a wrapper and not a template with the name changed. Auth, a paywall, and a settings screen are not a product. The distinctive feature still has to be in the binary. This is the rejection founders blame on Apple after shipping a reskin. The kit will not argue it for you.

    Guideline 4.3, spam and duplicate apps. A boilerplate makes this slightly easier to trip if you ship several apps that look identical. Change the product, not just the palette. The shell is allowed to rhyme. The app is not allowed to be the same app twice.

    Guideline 5.1.1 around privacy copy. Purpose strings, a real privacy policy URL in App Store Connect and in the app, and nutrition labels that match what PostHog, Analytics, and crash tools actually collect. The checklist covers the plist keys, including encryption export and tracking disclosure. The policy is a page you host. Analytics you do not document is a rejection you earned.

    Metadata. Screenshots of a different build, a description that promises a feature the binary does not have, a keyword field stuffed with a brand you do not own. None of that is in the repo.

    Play Store has a parallel list — data safety form, account deletion URL, and a feature graphic — and this post is about Apple because that is the review founders dread. The same shell helps on both, because the missing screen is usually the same screen.

    How to use the shell in a review cycle

    Build the unique feature on top of the existing auth, settings, and paywall. Do not let the agent replace them with a fresh version. That is the whole point of a canonical pattern.

    Submit a release build you have launched on a physical device. Increment the build number every upload. Strip debug menus. Create the demo account against the same backend the binary uses, and say so in the notes.

    Expect one rejection. Budget the week for it. The hygiene tickets above are what turn three rounds into one, and only if the buttons the reviewer taps are the buttons the shell already has.

    FAQ

    Does ShipAppFast guarantee App Store approval?

    No. Nothing does. It covers the shell items review keeps citing — Apple sign-in next to Google, in-app account deletion, store payments through RevenueCat and Superwall, a build that already runs. Your idea, your metadata, your privacy policy, and your demo account are still the review.

    What is the most common fix after a 5.1.1 rejection?

    Add account deletion inside the app, in account settings, and make it actually delete. If you use Sign in with Apple, revoke the token. If you sell a subscription, warn that Apple billing continues until they cancel. The screen exists in the kit. The backend call has to be true for your project.

    Can I use Stripe if RevenueCat is already wired?

    For physical goods, yes, and you will configure that yourself. For digital unlocks, no. Guideline 3.1.1 wants in-app purchase. Leave those on RevenueCat.

    What if review says the app is too simple?

    That is 4.2. Add the feature that made the app worth installing. A boilerplate cannot be that feature. It can make sure the rejection is about the feature, not about a missing delete button.

    Where is the submission checklist?

    The Flutter App Store submission checklist is the operational list: icons, purpose strings, encryption flag, demo account, build numbers. Read it the day you archive, not the day you start.

    The boring 80% includes the screens review already knows how to reject. Start on the other side of them with ShipAppFast.