From emasoft-complete-ios-app-authoring
Build, archive, validate, upload, and submit iOS/iPadOS/macOS/visionOS apps to App Store Connect via fastlane (match/gym/pilot/deliver), xcrun altool, or EAS (eas build / eas submit) for native Swift, React Native, Expo, Flutter, and Capacitor projects. Covers .xcarchive, ExportOptions.plist, code signing, PrivacyInfo.xcprivacy, TestFlight, ASC REST API metadata and screenshots, JWT-signed API keys, App Review submission, rejections, ITMS-XXXXX errors, macOS notarization (notarytool), and Xcode Cloud. Use when asked to submit to the App Store, ship to TestFlight, archive and upload, fastlane release, eas submit, fix code signing or ITMS-90xxx, notarize a Mac app, or respond to a rejection.
How this skill is triggered — by the user, by Claude, or both
Slash command
/emasoft-complete-ios-app-authoring:app-store-releaseThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
The solo-developer pipeline for shipping an iOS app to the App Store: build → archive
references/ASC-API.mdreferences/ASC-REST-RESOURCES.mdreferences/DELIVER-AND-METADATA.mdreferences/EAS-SUBMISSION.mdreferences/FASTLANE-SETUP.mdreferences/FRAMEWORK-BUILDS.mdreferences/GYM-AND-ARCHIVE.mdreferences/ITMS-ERRORS.mdreferences/MACOS-DISTRIBUTION.mdreferences/MATCH-AND-SIGNING.mdreferences/OPERATOR-PATTERNS.mdreferences/PILOT-AND-TESTFLIGHT.mdreferences/PRE-FLIGHT.mdreferences/PRIVACY-MANIFEST.mdreferences/REJECTIONS.mdreferences/XCODE-CLOUD.mdreferences/kernel-axioms.mdreferences/quick-start.mdThe solo-developer pipeline for shipping an iOS app to the App Store: build → archive → validate → upload → TestFlight → metadata → submit → post-review. Three pipeline shapes — pick one before touching anything:
xcrun altool + ASC web UI) — no tooling beyond Xcode. Best for the
first submission and TestFlight-only flows on native / Flutter / RN / Capacitor.
Often shorter than fastlane setup for a single ship.Framework-aware build routing collapses every project to one Xcode workspace (or a remote EAS build) before Phase 2; everything after that is framework-agnostic.
Scope and siblings. This skill owns the mechanical release act. For the deep pre-upload guideline-compliance audit (Sign in with Apple, account deletion, ATT, usage strings, IAP rules), use the
app-review-preflightskill first — it catches rejections while they're cheap. For keyword research, listing copywriting, and store-screenshot design, useapp-store-optimization. For icon generation / validation, useapp-icons. This skill cross-references those but does not duplicate them; it keeps only the slices that are mechanically part of pushing a binary live (the ASC REST upload protocols, device-size enums, age-rating field discovery, and a post-rejection response loop).
Full axiom text (war stories, exact error strings, OP cross-references): kernel-axioms. The headlines:
.xcarchive is the choke point — after a Distribution-signed archive with dSYMs, every framework's pipeline is identical.xcodebuild/altool/EAS-dashboard error before retrying anything.--validate-app catches ITMS errors in ~30s vs a 5–30 min processing round-trip.PrivacyInfo.xcprivacy + signed SDK manifests, verified at validation time (references/PRIVACY-MANIFEST.md)..p8/JWT; every mutating ASC call needs explicit user confirmation (references/ASC-API.md).First-submission strategy: fill metadata/screenshots/age-rating/review-info once in the ASC web UI (faster than a
Deliverfilefrom scratch); adopt fastlane after the first ship.
Pick exactly one. Each routes to a different subset of phases.
| Mode | Trigger | Phases run |
|---|---|---|
first-submission | App not yet in ASC, never released | 0 → 8 (full) |
update | Existing app, new build/version | 0 → 8, skip ASC record creation + agreements + age rating in 6 |
testflight-only | Internal beta, no Store release this cycle | 0 → 5, stop |
metadata-only | Description / screenshots / keywords / privacy change only | 6 → 7, skip 0–5 |
resubmission-after-rejection | Apple rejected the previous build | start at references/REJECTIONS.md, then resume from the earliest affected phase |
xcode-version-rebuild | New Xcode/SDK forces re-archive (annual iOS bump) | 0 → 8 + Xcode-compat audit at Phase 0 |
Each framework collapses to a buildable Xcode workspace or a remote EAS build. After Phase 1, every later phase is framework-agnostic.
| Framework | Pipeline | Pre-Xcode step | Workspace path |
|---|---|---|---|
| Native (Swift/SwiftUI/UIKit) | fastlane / altool | bundle exec pod install if a Podfile exists; for XcodeGen repos xcodegen generate first (OP-39) | MyApp.xcworkspace (or .xcodeproj if no Pods, or generated from project.yml) |
| React Native (bare, no EAS) | fastlane | cd ios && bundle exec pod install | ios/MyApp.xcworkspace |
| Expo (managed) | EAS | eas build --platform=ios --profile=production | n/a (cloud build) |
| Expo (bare) / RN with EAS | EAS (recommended) or fastlane | eas build or npx expo prebuild && cd ios && pod install | n/a or ios/<App>.xcworkspace |
| Flutter | fastlane / altool | flutter build ios --release --no-codesign | ios/Runner.xcworkspace |
| Capacitor | fastlane | npx cap sync ios | ios/App/App.xcworkspace |
Detection: if app.config.js / app.json has an expo: key, or eas.json exists
at project root, treat it as an Expo project and prefer EAS unless you have a strong
reason for fastlane (custom CI runners, air-gapped builds). Otherwise default to
bare-bones for the first submission and graduate to fastlane when repeat-release pain
justifies it.
→ See references/FRAMEWORK-BUILDS.md for per-framework command sequences; references/EAS-SUBMISSION.md for the full EAS pipeline.
Copy-paste command sequences for all three paths live in
quick-start: A. bare-bones (4 commands — build,
IPA-content verify, altool validate, upload — plus the ASC web-UI pass and the
VALID poll), B. fastlane (fastlane init, the minimal release lane, the
per-framework one-liners), C. EAS (eas build + eas submit with the
ascAppId pre-flight), and the one-time ASC API key setup (where to generate,
.p8 storage convention, Key ID vs Issuer ID 401 trap, App Manager vs Admin role).
Know the CLI-vs-web-UI boundary before you start — don't hunt for a fastlane action
that doesn't exist. Builds, signing sync, build-number bumps, upload, metadata,
screenshots, and the review submit recur via fastlane/EAS; Developer Program enrollment,
Agreements/Tax/Banking, first app-record creation (no public POST /v1/apps — OP-42),
privacy nutrition labels, export compliance, and age rating are one-time web-UI items
(Phase 0). Full per-step fastlane/EAS table + the web-UI-only list + Xcode Cloud / macOS
pointers: PRE-FLIGHT — Automation coverage, plus the
one-time setup walkthrough in the same file.
Each phase has a hard gate; do not proceed without the listed evidence.
Gate: every checklist item verified in ASC / the Apple Developer portal — program
membership paid, agreements/tax/banking, ASC record, bundle-ID consistency,
ITSAppUsesNonExemptEncryption (OP-24), version strictly above the latest approved train
(OP-30); plus per-path items (local Distribution cert in the keychain — OP-4, profile,
ASC key for fastlane; eas whoami + ascAppId for EAS). Full per-path checklists:
PRE-FLIGHT — Phase 0 gate checklists; also
references/FASTLANE-SETUP.md, references/EAS-SUBMISSION.md.
Gate: Xcode opens the workspace and builds the Release scheme without errors. Plus: app icon and launch screen are not framework defaults.
Apply the framework router. Fail fast on dependency-install errors before touching Xcode — they're cheaper to diagnose than archive failures.
Critical placeholder-asset check (the silent App Review rejection trap):
flutter create / RN / Capacitor scaffolds ship default placeholder
icons that pass binary validation but get rejected at App Review under Guideline 4.0
(OP-1). Visually inspect the 1024×1024 source before Phase 2. Verify size + no-alpha
with sips -g pixelWidth -g pixelHeight -g hasAlpha <icon> (OP-46). If it's the
framework default, regenerate (see the app-icons skill, or
flutter_launcher_icons).LaunchScreen.storyboard is customized — default storyboards
reference a 68-byte placeholder (OP-2). If hand-writing a storyboard for Xcode 26,
stay in the legacy format or Xcode's IB compiler may throw an internal error (OP-7).→ references/FRAMEWORK-BUILDS.md.
fastlane gym / xcodebuild / eas build)Gate: valid .xcarchive with embedded dSYMs at a known path, Distribution-signed
(fastlane/altool); or FINISHED build with a downloadable IPA URL (EAS).
fastlane gym \
--workspace ios/MyApp.xcworkspace \
--scheme MyApp --configuration Release \
--export_method app-store \
--output_directory build --include_symbols true
EAS path: eas build --platform=ios --profile=production --non-interactive --no-wait,
then poll eas build:view <id> --json until status=FINISHED (5–10 min).
→ references/GYM-AND-ARCHIVE.md for ExportOptions.plist templates (use
method: app-store-connect — OP-38), manual-signing variants, and the two-stage
archive/export signing model (OP-40). For native/XcodeGen, put signing in project.yml,
never the .xcodeproj (OP-39).
Gate: validation returns success; all ITMS errors resolved.
xcrun altool --validate-app -f build/MyApp.ipa -t ios \
--apiKey <KEY_ID> --apiIssuer <ISSUER_ID>
gym runs validation by default. Common failures: missing privacy manifest, missing
usage descriptions, encryption-export gaps, wrong provisioning profile, deprecated APIs.
→ references/PRIVACY-MANIFEST.md, references/ITMS-ERRORS.md.
fastlane pilot / xcrun altool / eas submit)Gate: build appears in ASC → TestFlight → Builds, processing complete (~5–30 min).
# fastlane
fastlane pilot upload --ipa build/MyApp.ipa \
--skip_waiting_for_build_processing false --skip_submission true
# EAS
eas submit --platform=ios --latest --non-interactive
Use the ASC API key over Apple-ID + app-specific-password (required in CI). EAS surfaces Apple-side errors only at the submission URL (OP-29).
⚠ Version-train constraint: the version in this build must be higher than the latest approved App Store version — TestFlight-only included (ITMS-90062 + ITMS-90186, OP-30). Bump before re-uploading after an approval.
→ references/PILOT-AND-TESTFLIGHT.md (fastlane + altool), references/EAS-SUBMISSION.md.
Gate: build installs and launches on at least one real device via TestFlight.
→ references/PILOT-AND-TESTFLIGHT.md.
Gate: all required ASC fields populated.
For keyword research, listing copywriting, and store-screenshot design, use the
app-store-optimizationskill — that's where the ASO craft lives. This phase covers only the mechanics of getting the fields and assets into ASC.
Three paths — pick once and stick with it: A fastlane deliver (committed source of
truth, repeat releases / CI), B ASC REST API direct (JWT script — mind the 3-step
screenshot protocol OP-22, annual age-rating expansion OP-17/18, the APP_IPHONE_67
device-size enum OP-21), C ASC web UI (recommended first submission; sole
authoritative privacy-label + age-rating questionnaire). EAS builds are garbage-collected
after 30 days (OP-32) — don't sit on metadata. Per-path detail + the full required-field
list (name/subtitle/keywords limits, screenshots, privacy labels, copyright):
DELIVER-AND-METADATA — Phase 6.
Gate: submission accepted; state moves PREPARE_FOR_SUBMISSION → WAITING_FOR_REVIEW.
Note: a build showing "Ready to Submit" in TestFlight is not "Submitted" — the
review submission is a separate action (OP-13).
Attach demo-account credentials, review notes, and the phased/manual release choices,
then submit via fastlane deliver --submit_for_review true or the ASC REST 3-call
sequence — the submit is a PATCH … {submitted:true}, not an actions/submit (OP-47),
and a stale UNRESOLVED_ISSUES submission must be cancelled first (OP-48). Exact
commands + REST calls + post-submit state verification:
DELIVER-AND-METADATA — Phase 7 and
references/ASC-REST-RESOURCES.md.
This is the irreversible action. ALWAYS require explicit user authorization before firing the final submit — never submit programmatically without confirmation (axiom 12).
Gate: approved + released, OR rejection handled and resubmission queued.
On rejection, references/REJECTIONS.md is the entry point: read the cited guideline verbatim, reproduce locally against the exact build the reviewer saw, fix the root cause, scan for the same pattern elsewhere, then resubmit. Do all four before replying.
kernel-axioms.md — the 12 operating axioms in full (war stories, exact error strings, OP cross-references).
quick-start.md — copy-paste bare-bones / fastlane / EAS command sequences + one-time ASC API key setup.
PRE-FLIGHT.md — Apple Developer / ASC setup, certs, provisioning, bundle-ID hygiene, credential sanity-check, CLI-vs-web-UI automation coverage.
FRAMEWORK-BUILDS.md — Native / RN / Expo / Flutter / Capacitor pre-iOS-build steps + dependency-install errors.
FASTLANE-SETUP.md — Bundler-managed install, Appfile, lane structure, recommended lanes.
EAS-SUBMISSION.md — EAS Build + Submit for Expo: config, polling, error reading, fastlane migration.
MATCH-AND-SIGNING.md — fastlane match, cert storage/sync, manual-signing fallback, common signing errors.
GYM-AND-ARCHIVE.md — gym config, ExportOptions.plist templates, raw xcodebuild archive/-exportArchive.
PILOT-AND-TESTFLIGHT.md — pilot/altool upload, JWT minting, the 3-state poll loop, tester groups, Beta App Review, version-train semantics, ASC state verification.
DELIVER-AND-METADATA.md — deliver layout, screenshot capture (3 paths) + upload/reorder/replace protocols, age-rating, the submit (PATCH {submitted:true}), phased-release curve, idempotent diff-before-write, ASC enum/limit reference.
PRIVACY-MANIFEST.md — PrivacyInfo.xcprivacy, required-reason APIs + reason codes, the enumerated "commonly used SDK" list, the iOS-26/Xcode-26 SDK floor-version table, third-party SDK signatures.
ITMS-ERRORS.md — Catalog of common ITMS-XXXXX errors/warnings (incl. 90475, 90348, the iOS-17 split permission keys, non-ITMS archive errors) with cause / fix / prevention.
ASC-API.md — Secrets-hygiene model, ~/.asc_secrets, the safe JWT client, the 401/403 troubleshooting table, OpenAPI-template script, asc-mcp + the asc community CLI.
ASC-REST-RESOURCES.md — ongoing-management REST: customer reviews + AI summaries, gzip-TSV sales/finance reports, in-app-events/custom-product-pages/app-clips, recovering a stuck submission.
MACOS-DISTRIBUTION.md — MAS .pkg (cert pools, embed profile, SwiftPM 409, actool 90546/90236), Developer-ID notarization (hardened runtime, notarytool, staple+re-zip, broken-trust repair), SwiftPM .app packaging, Sparkle appcast.
XCODE-CLOUD.md — Apple-native CI: the three ci_scripts/, the CI_* env table, the two release scripts (WhatToTest, version↔tag), workflows, troubleshooting, the compute-hour cost model.
REJECTIONS.md — App Review Guideline routing (2.1 / 4.0 / 4.3 / 5.1.1 / 3.1.1 …), the four-step response loop, fix-time/strategy/seasonal tables, named-AI consent, Resolution Center templates, appeals.
OPERATOR-PATTERNS.md — Session-mined gotchas in OP-N format (OP-1 … OP-63). Placeholder-icon traps, cloud-signing fragility, ASC API quirks, screenshot upload protocol, age-rating discovery, EAS traps, zero-fastlane Flutter flow, XcodeGen/native-Swift signing, the correct submit endpoint (OP-47), cancel-stale-submission (OP-48), server-authoritative build numbers (OP-61), extension 90348, locale crash, and more.
Reading order by project type:
ASC-API.mdaltool zero-fastlane: OP-34, OP-35, OP-36, OP-37, OP-38, OP-46, OP-52, OP-60REJECTIONS.mdMACOS-DISTRIBUTION.md, XCODE-CLOUD.mdnpx claudepluginhub emasoft/emasoft-complete-ios-app-authoring --plugin emasoft-complete-ios-app-authoringBlocks Edit/Write/Bash actions until Claude investigates importers, data schemas, and user instructions. Improves output quality by forcing concrete facts before edits.