Guideline 2.1 (Performance – App Completeness) rejections are short. 2.1(a) says one or more bugs were found, with a device model and version. 2.1(b) says the review could not be completed. A first submission that hits it usually produces the same first reaction: "I can't reproduce that." That reaction is the answer.
This comes from our own submissions across a portfolio of small apps. Three patterns covered most of them.
1. Cold start is the review environment
Every test you run is a hot path: data is there, permissions are granted, you have walked the main flow a hundred times, on your favourite device. A 1.0 only gets one real cold start before release, and it lands on the reviewer: empty data, every permission prompt unanswered, a device you did not choose (one of ours named an iPad Air), entering through the door you never use.
Builds and tests that pass show the parts work, not that the product works in a stranger's first five minutes.
Reproduce it their way:
- Read the message first. The device model marks which form factor was tested; follow the reproduction steps if any, not your habitual path.
- Erase a simulator (Erase All Content and Settings), install the exact build you submitted, deny every permission prompt, and start with the least obvious entry: an empty list, Settings, a secondary tab, rotation, backgrounding.
- Make "a stranger's first five minutes" a fixed step before every submission. It catches the paths you never walk naturally, so testing the same flow more times does not replace it.
2.1(b) adds that the review needs to run on both a phone and a tablet shape, so the core flow has to complete on both.
2. The purchase button that freezes while every check is green
The payment tap is the one path where compile, unit tests, a rendered paywall and a called purchase API can all pass while the subscribe button freezes or errors when actually pressed. We had two 2.1(a) rejections like this, one frozen button and one error on tap, and in both the checks on the submitted build were green. Those signals are intermediate; the failure lives below the level they look at.
- Define one success signal: the full purchase completes and the entitlement is granted. A loaded product, a rendered page or a called API is not success.
- Drive it with a UI test that taps the real button, waits, and asserts the unlocked state, also after a restart.
- An intermittent failure is not a flaky test; it is the defect, sampled at its own failure rate. Find the stage it stalls at: did the product load, did the transaction start, did the confirmation sheet close? A green re-run is another sample, never a closure.
3. In-app purchases that were never submitted
A tvOS app of ours got 2.1(b) because it referenced paid content whose in-app purchase had not been submitted for review. The build was valid and every local check passed; "was the purchase submitted with this version" lives only in App Store Connect. Several platform facts stack into a blind spot: a product sitting at Ready to Submit is not the same as submitted with this version; uploading a new build does not attach pending purchases; attaching a purchase to a version is a web-only action; and a purchase missing its review screenshot stays in Missing Metadata and does not even appear in the version's list.
Fix it in order: make the product submittable (localized metadata plus an opaque, non-alpha review screenshot), submit each purchase for review, then attach each one to the version. Then add a check: list every product ID the app references, compare with what is attached to the version, and block submission on any that is referenced but not attached.
One-minute check
Erase a simulator, install the current build, deny all permissions, and take the first path away from the main flow with empty data. Then open the paywall on a fresh install, note every purchase it shows, and confirm each is listed and submitted on the version page in App Store Connect. A blank, a freeze or a crash on the first, or a product ID missing on the second, is what the reviewer would have found first.
These notes are from Obelisk Club's own submissions. Apple's wording and tools change; check the current App Review Guidelines and App Store Connect for exact behaviour.