For two weeks after the Golden Week holiday, I spent my mornings on a quiet, slightly heavy task: rolling out a Privacy Manifest update across six iOS wallpaper apps. The first submission came back with a rejection, and the short memo I wrote to myself that afternoon ended up rescuing the remaining five. This article is the operational note from that two-week stretch. Rather than walking through the implementation details, I want to focus on the choreography of moving six apps in parallel, and on how the failure of the first one was translated into a checklist for the next five.
Implementation specifics on Required Reason API and SDK-chain auditing already live in two earlier posts on this site, so this one stays firmly on the operations side.
Why Run Six Apps in Parallel at All
I originally planned to ship the apps one by one. With Apple's review times being unpredictable that week, taking the risk on a single app before moving on felt safer. What changed my mind was realising that the actual Privacy Manifest content was almost identical across all six apps — AdMob, Firebase, RevenueCat, and MMKV were on the same versions, and the PrivacyInfo.xcprivacy payload was about 80 percent shared.
Both of my grandfathers were temple carpenters, and one of them used to say that "if the cuts are the same, cut them all at once before you start joining anything." If the preparation cost is roughly the same for one app as it is for six, then it makes sense to audit and fix in parallel, even if the actual submissions are staggered. I ended up with a hybrid approach: audit and fix all six together, but submit them in three waves of two apps each.
Three Lessons from the First Rejection
The first submission was rejected not with the usual ITMS-91053 error but with a note that the Privacy Nutrition Label disclosed on App Store Connect did not match the NSPrivacyTrackingDomains entries in the Manifest. The wording was polite, but the underlying issue was a mismatch rather than a missing declaration.
I took three concrete lessons away from this.
First, always look at the Privacy Manifest and the App Store Connect Nutrition Label as a pair. Cleaning up the Manifest alone is not enough — if the Connect-side checkboxes still reflect the older design, the submission comes back as a mismatch.
Second, the scope of NSPrivacyTrackingDomains is wider than I had been treating it. Ad-serving domains and A/B routing domains need to be inventoried alongside the analytics domains. In my case, the direct cause of the rejection was forgetting to declare googleads.g.doubleclick.net.
Third, the rejection text itself doubles as a checklist for the next submission. Apple's responses rarely spell out the reasoning, but the quoted line numbers and the SDK names mentioned in the body are usually enough to infer where to look in the next app.
How I Translated the First Failure into the Next Five
On the same day the first app was rejected, I wrote a one-page memo for myself. It contained:
- The rejection reason in a single sentence
- The exact declaration that was wrong and the diff that fixed it
- A 5×3 checklist of places in the remaining five apps where the same symptom could appear
- Five items on the Connect-side Nutrition Label that needed to be re-verified
- Detection rules to fold back into the audit script later
I started calling this a "translation template." Not a per-app changelog, but a short procedure for applying one app's failure to the remaining N apps. The Manifest fixes on the next five apps each took about thirty minutes, and the Connect-side Label adjustments fifteen to twenty minutes per app. All five resubmissions passed on the first attempt.
Writing the memo took about forty minutes. If I had skipped it and handled the next five ad hoc, I am fairly sure I would have walked into a similar rejection somewhere around the third app.
Designing the Phased Release Rings
I considered putting all six apps on a maximum-duration Phased Release at the same time, but landed on a three-ring layout instead.
Ring 1 (two apps) holds the apps with lower install bases and the most direct user feedback channels. Phased Release is set to its shortest configuration, prioritising fast detection of regressions. Ring 2 (two apps) holds the mid-sized, revenue-critical apps; these are submitted only after Ring 1's first 24 hours come back clean. Ring 3 (two apps) holds the largest DAU apps, and is held back until Ring 2 has been quiet for 72 hours.
The ring design accounts for a quirk of wallpaper apps: a Privacy Manifest update has no visible UI change, which means there is little reason for users to manually relaunch the app. The propagation from release to actual device adoption is slower than a typical UI update, and the release calendar has to be designed around that delay.
Using Claude in Chrome to Watch Six Connect Pages
Manually checking six App Store Connect pages every morning was never going to last. Instead, I had Claude in Chrome cycle through six tabs each morning and extract three things:
- Apps whose review status changed in the last 24 hours
- New Crashlytics stack traces or sudden upticks in crash-free rate
- New user reviews containing the words "update," "ads," or "doesn't work"
The output came back as a short bullet list, and I only opened the tabs that actually needed my attention. Running six apps in parallel, the cognitive overhead of switching browser tabs alone is surprisingly draining; letting an AI do the first-pass filtering helped more than I expected. Having shipped indie apps since 2014 and accumulated roughly 50 million downloads across the catalogue, I have come to feel that letting an AI handle anomaly detection — rather than trying to eyeball every app every day — is what actually extends the lifespan of a portfolio.
What Six Parallel Submissions Actually Taught Me
Three takeaways to close on.
First, the essence of running things in parallel is not the fix itself, it is the translation of failure. If you can compress your first rejection into a one-page memo, the remaining N apps effectively become copies of a corrected release.
Second, do not assume that a UI-less Privacy Manifest update needs less Phased Release care. The slow device-side adoption actually argues for a more cautious ring design, not a looser one.
Third, running six apps as a single indie developer is not parallel work — it is parallel observation. Implementation stays sequential and human; only the watching is delegated to the AI. Once the layout settles into that shape, the cognitive load drops noticeably.
If you find yourself in a similar position next time, leave a blank page in your notes labelled "translation template" before you submit the first app. That single page tends to change how the second submission feels.