---
name: apple-store-submit
description: Handle Apple App Store rejection emails end-to-end: parse rejection reasons, create a fix plan, implement code changes (privacy strings, entitlements, sandbox), navigate App Store Connect to update metadata, and resubmit. Use when an app receives a rejection or when preparing a first-time submission.
license: MIT
allowed-tools: Bash, Read, Write, Edit
compatibility: Codex, Claude Code, Cursor, GitHub Copilot, Windsurf, Kiro, and other Agent Skills compatible tools. Requires Xcode, an Apple Developer account, and App Store Connect access.
metadata:
  targets: [_source-only]
  author: Oleg Koval
  tags:
    - apple
    - app-store
    - ios
    - macos
    - xcode
    - submission
    - rejection
---

> 🤖 *Auto-generated by **weekly-pattern-learner** · App Store rejection handling workflow observed in FocusNotch App Store session, Jun 2026 (92 user turns covering rejection → plan → code fixes → metadata → resubmit)*

# Apple App Store Submission & Rejection Handling

## Overview

Parse Apple rejection feedback, implement targeted fixes, update App Store Connect metadata, and resubmit, covering the complete cycle from rejection email to approved build.

## When to Use

- Apple review team sends a rejection email
- App fails automated pre-review checks (binary rejected at upload)
- Preparing metadata for first-time submission (screenshots, keywords, privacy labels)
- Resolving App Store Connect errors before submitting for review

## Workflow

### 1. Parse the Rejection

Read the full rejection email. Extract and list:

- **Guideline numbers** violated (e.g., 2.1, 4.2.0, 5.1.1)
- **Code-level issues**: missing entitlements, incorrect privacy strings, sandbox violations
- **Metadata issues**: wrong screenshot sizes, subtitle policy, keyword stuffing
- **UX issues**: crashes described by reviewer, broken flows, missing functionality

Create a numbered fix plan: one item per rejection point, with the type of fix needed.

### 2. Classify Fixes by Type

| Type | Location |
|------|----------|
| Privacy usage strings missing | `Info.plist` |
| Entitlement missing/wrong | `<AppName>.entitlements` |
| Crash or broken feature | Source code |
| Screenshots wrong size/content | App Store Connect |
| Keywords/subtitle/description | App Store Connect |
| Build number conflict | Xcode + App Store Connect |

### 3. Implement Code Fixes

**Privacy permission strings** (`Info.plist`):

```xml
<key>NSMicrophoneUsageDescription</key>
<string>Used for voice input during focus sessions.</string>

<key>NSCalendarsUsageDescription</key>
<string>Used to sync tasks with your calendar.</string>
```

**Entitlements** (`<AppName>.entitlements`):

```xml
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
```

**Sandbox violations**: remove `NoEscapeBlock` patterns, replace deprecated APIs, use only sandboxed file access via Security-Scoped Bookmarks when needed.

### 4. Build and Archive

```bash
# Clean build
xcodebuild clean \
  -scheme <AppName> \
  -destination 'generic/platform=macOS'

# Archive
xcodebuild archive \
  -scheme <AppName> \
  -archivePath build/<AppName>.xcarchive \
  -destination 'generic/platform=macOS'

# Export for App Store
xcodebuild -exportArchive \
  -archivePath build/<AppName>.xcarchive \
  -exportPath build/export \
  -exportOptionsPlist ExportOptions.plist
```

Validate codesigning before upload:

```bash
codesign --verify --deep --strict --verbose=4 build/export/<AppName>.app
spctl --assess --verbose=4 build/export/<AppName>.app
```

### 5. Update App Store Connect Metadata

Navigate: **My Apps → [App] → App Store tab**

Common metadata fixes:

- **App name**: max 30 chars
- **Subtitle**: max 30 chars, no duplicate keywords from the title field
- **Keywords**: 100-char total limit, comma-separated, no spaces after commas
- **Screenshots**: exact pixel dimensions per device type (check Apple's current spec)
- **Privacy Nutrition Labels**: must accurately reflect data collected/linked to user
- **Build selection**: select the newly uploaded build before submitting

### 6. Write Reviewer Notes

In the submission form, fill **Notes for Reviewer**:

- Explain each rejection point and what was changed
- Reference specific guideline numbers: "Addressing 2.1: added NSMicrophoneUsageDescription to Info.plist"
- If a feature requires special credentials to test, provide test account details

### 7. Submit and Track

1. Upload via **Xcode Organizer → Distribute App → App Store Connect**
2. In App Store Connect: select the new build, fill notes, **Submit for Review**
3. Typical re-review: 24–48h
4. If rejected again: respond in the **Resolution Center** thread (same case number)
5. Escalate via Resolution Center for policy disagreements: do not open a new submission

## Build Number Protocol

Apple rejects builds with a duplicate build number. Increment `CFBundleVersion` in `Info.plist` or Xcode target settings before every upload:

```bash
# Bump build number (e.g., 9 → 10)
xcrun agvtool new-version -all 10
```

## Verification

- [ ] Every rejection guideline number has a corresponding fix in the plan
- [ ] `xcodebuild archive` exits 0 with no warnings about entitlements
- [ ] `codesign --verify` passes
- [ ] App Store Connect shows build status as "Ready to Submit"
- [ ] Reviewer Notes reference each changed item
- [ ] Build number is higher than any previously uploaded build
