REFApps

Internal playbook

App Store Upload Lessons

Hard-won fixes from REFApps submissions. Apply before every Archive / Submit.

Source ·
Brick Calculator Plus (com.appstore.brickcalculator)
First submission ·
Sep 2026
Updated ·
2026-09-06

What hurt us

IssueCauseFix for next apps
ITMS orientation / iPad multitaskingPortrait-only without opt-outAlways set UIRequiresFullScreen = true in Info.plist for iPhone-first apps
ITMS-91064 Invalid Binary (PrivacyInfo)NSPrivacyTracking = true + empty NSPrivacyTrackingDomainsIf tracking = true → list real domains (e.g. AdMob). Else set tracking = false and keep domains empty
CFBundleVersion stuck at 1Hardcoded version in Info.plist ignored project.ymlUse $(MARKETING_VERSION) and $(CURRENT_PROJECT_VERSION) in Info.plist
Screenshot dimension rejectsWrong simulator (e.g. iPhone 17 Pro = 1206×2622)Shoot on iPhone 16 Pro Max (6.7") and prepare 13" iPad sizes even for iPhone-only
App Privacy blocks SubmitATT present but no “Data Used to Track You” + not PublishedDeclare Advertising Data / Device ID with Tracking = Yes, then click Publish (Admin)
Guideline 2.1 — Information NeededNew Apple Developer accountPrepare screen recording + written answers before first Submit
TestFlight “No builds” / invite codeBuild not assigned / Apple ID mismatch / Internal vs ExternalAssign build to Internal group; same Apple ID; or skip TestFlight and submit from ASC
dSYM “Upload Symbols Failed”Firebase / Google binary SDKsIgnore — not a blocker

One-line rules

  1. Never NSPrivacyTracking = true with empty domains.
  2. Always bump build before re-upload.
  3. Always UIRequiresFullScreen for portrait iPhone apps.
  4. Always Publish App Privacy as Admin when ATT exists.
  5. Always prepare iPad 13" screenshots until ASC stops asking.
  6. Ignore Google/Firebase dSYM upload warnings.
  7. First app on a new account = expect “information needed,” not silence.

Pre-flight checklist

Project / signing

  • DEVELOPMENT_TEAM set in project.yml → xcodegen generate
  • Signing works on a physical device
  • Bundle ID registered; In-App Purchase capability if needed
  • MARKETING_VERSION + CURRENT_PROJECT_VERSION via $(…) in Info.plist
  • Bump build number on every upload

Info.plist / privacy binary

  • UIRequiresFullScreen = true (if not supporting iPad multitasking)
  • ITSAppUsesNonExemptEncryption = false (if applicable)
  • AdMob: GADApplicationIdentifier + banner + interstitial unit IDs
  • NSUserTrackingUsageDescription if ATT / personalized ads
  • PrivacyInfo.xcprivacy valid (tracking false+empty OR true+domains)
  • App icon 1024×1024; launch screen OK

Store listing

  • Copy file per app (name, subtitle, keywords ≤100, description, review notes)
  • Screenshots: iPhone 6.7" + 13" iPad if ASC requires
  • Support URL + Privacy Policy URL live
  • Working support email
  • Site text matches real app features

App Privacy questionnaire (ASC)

  • Privacy Policy URL
  • Collect data = Yes (if ads/analytics)
  • Advertising Data / Device ID → Used for Tracking = Yes when ATT exists
  • Click Publish (user must be Admin)

Screenshot sizes

SlotAccepted examplesPractical tip
iPhone (common)1284×2778, 1290×2796, 1320×2868Simulator: iPhone 16 Pro Max; or resize with sips
iPad 13"2064×2752, 2048×2732Even iPhone-only apps often required this

Upload flow

  1. 01Fix code / plist / privacy manifest
  2. 02Bump CURRENT_PROJECT_VERSION
  3. 03xcodegen generate
  4. 04Xcode: Any iOS Device → Clean → Archive → Upload
  5. 05Ignore Firebase/AdMob dSYM warnings if Upload Successful
  6. 06Wait Processing (10–40 min)
  7. 07ASC: select new build on version page
  8. 08Submit for Review

Canonical markdown also lives at store-docs/APP_STORE_UPLOAD_LESSONS.md. Update both after each new submission.