Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Apple App Store submission and management expertise
.claude/skills/a5c-ai-app-store-connect/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 53% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 159% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 115% | 0% |
| case-17 | ✗→✓ | ▲ Improved | 59% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 134% | 0% |
This skill provides comprehensive capabilities for Apple App Store submission and management. It enables interaction with App Store Connect API, metadata management, TestFlight distribution, and app lifecycle management.
bash - Execute xcrun, altool, and Transporter commandsread - Analyze app metadata and configuration fileswrite - Generate metadata files and API configurationsedit - Update app store metadataglob - Search for metadata and screenshot filesgrep - Search for patterns in configurationsThis skill integrates with the following processes:
ios-appstore-submission.js - App Store submissionbeta-testing-setup.js - TestFlight configurationapp-store-optimization.js - ASO metadataautomated-release-management.js - Release automationbash# Generate API key in App Store Connect # Users and Access > Keys > App Store Connect API # Key file structure AuthKey_XXXXXXXXXX.p8
bash# App Store Connect API export APP_STORE_CONNECT_API_KEY_ID="XXXXXXXXXX" export APP_STORE_CONNECT_API_ISSUER_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" export APP_STORE_CONNECT_API_KEY_PATH="./AuthKey_XXXXXXXXXX.p8" # Alternative: Base64 encoded key export APP_STORE_CONNECT_API_KEY="$(cat AuthKey.p8 | base64)"
bash# Validate IPA xcrun altool --validate-app \ --file ./build/MyApp.ipa \ --type ios \ --apiKey XXXXXXXXXX \ --apiIssuer xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # Upload IPA xcrun altool --upload-app \ --file ./build/MyApp.ipa \ --type ios \ --apiKey XXXXXXXXXX \ --apiIssuer xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
ruby# fastlane/Deliverfile app_identifier("com.example.myapp") username("developer@example.com") # Metadata name({ "en-US" => "My Awesome App", "es-ES" => "Mi Aplicacion Increible" }) subtitle({ "en-US" => "The best app ever", "es-ES" => "La mejor app del mundo" }) # Keywords (comma-separated) keywords({ "en-US" => "productivity,tasks,notes,todo", "es-ES" => "productividad,tareas,notas" }) # URLs support_url("https://example.com/support") marketing_url("https://example.com") privacy_url("https://example.com/privacy") # App Review Information app_review_information( first_name: "John", last_name: "Doe", phone_number: "+1 555 555 5555", email_address: "review@example.com", demo_user: "demo@example.com", demo_password: "demo123", notes: "Demo account is pre-configured with sample data" ) # Submission submit_for_review(false) automatic_release(false) phased_release(true) # Precheck precheck_include_in_app_purchases(false)
fastlane/metadata/
├── en-US/
│ ├── name.txt
│ ├── subtitle.txt
│ ├── description.txt
│ ├── keywords.txt
│ ├── release_notes.txt
│ ├── promotional_text.txt
│ ├── support_url.txt
│ ├── marketing_url.txt
│ └── privacy_url.txt
├── es-ES/
│ └── ... (same structure)
├── review_information/
│ ├── first_name.txt
│ ├── last_name.txt
│ ├── phone_number.txt
│ ├── email_address.txt
│ ├── demo_user.txt
│ ├── demo_password.txt
│ └── notes.txt
├── copyright.txt
├── primary_category.txt
├── secondary_category.txt
└── trade_representative_contact_information/fastlane/screenshots/
├── en-US/
│ ├── iPhone 15 Pro Max-1_home.png
│ ├── iPhone 15 Pro Max-2_feature.png
│ ├── iPhone 15 Pro Max-3_settings.png
│ ├── iPhone 15 Pro-1_home.png
│ ├── iPad Pro (12.9-inch)-1_home.png
│ └── ...
└── es-ES/
└── ...swift// Example: Fetching apps using App Store Connect API import Foundation struct AppStoreConnectClient { let keyId: String let issuerId: String let privateKey: String func generateToken() -> String { // Generate JWT token let header = ["alg": "ES256", "kid": keyId, "typ": "JWT"] let payload = [ "iss": issuerId, "exp": Int(Date().addingTimeInterval(20 * 60).timeIntervalSince1970), "aud": "appstoreconnect-v1" ] // Sign with ES256 return jwt } func fetchApps() async throws -> [App] { let url = URL(string: "https://api.appstoreconnect.apple.com/v1/apps")! var request = URLRequest(url: url) request.setValue("Bearer \(generateToken())", forHTTPHeaderField: "Authorization") let (data, _) = try await URLSession.shared.data(for: request) let response = try JSONDecoder().decode(AppsResponse.self, from: data) return response.data } }
ruby# fastlane/Fastfile lane :beta do # Build gym(scheme: "MyApp") # Upload to TestFlight pilot( skip_waiting_for_build_processing: false, distribute_external: true, notify_external_testers: true, # Beta groups groups: ["Internal Testers", "External Beta"], # Changelog changelog: "Bug fixes and performance improvements", # Beta App Review beta_app_review_info: { contact_email: "review@example.com", contact_first_name: "John", contact_last_name: "Doe", contact_phone: "+1 555 555 5555", demo_account_name: "demo@example.com", demo_account_password: "demo123", notes: "Testing instructions here" }, # Localized info localized_build_info: { "en-US" => { whats_new: "Bug fixes and improvements" }, "es-ES" => { whats_new: "Correcciones y mejoras" } } ) end
json{ "iaps": [ { "product_id": "com.example.premium_monthly", "type": "auto_renewable_subscription", "reference_name": "Premium Monthly", "subscription_group": "Premium", "pricing": [ { "country": "USA", "price_tier": 4 } ], "localizations": [ { "locale": "en-US", "name": "Premium Monthly", "description": "Unlock all premium features" } ] } ] }
fastlane-cicd - Build automationswift-swiftui - iOS developmentmobile-security - App security| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 8,632 | 12,401 | +44% | 1 | 1 | 0% | 1,384 | 3,234 | +134% | 0 | 0 | — |
case-02 | fail→pass | 12,812 | 7,658 | -40% | 1 | 1 | 0% | 2,456 | 3,746 | +53% | 0 | 0 | — |
case-03 | pass→pass | 5,526 | 6,690 | +21% | 1 | 1 | 0% | 1,103 | 3,519 | +219% | 0 | 0 | — |
case-04 | pass→pass | 6,752 | 5,676 | -16% | 1 | 1 | 0% | 1,008 | 3,385 | +236% | 0 | 0 | — |
case-05 | pass→pass | 9,986 | 7,064 | -29% | 1 | 1 | 0% | 1,795 | 3,956 | +120% | 0 | 0 | — |
case-06 | pass→pass | 5,553 | 5,172 | -7% | 1 | 1 | 0% | 819 | 3,205 | +291% | 0 | 0 | — |
case-07 | pass→pass | 4,448 | 5,481 | +23% | 1 | 1 | 0% | 513 | 3,324 | +548% | 0 | 0 | — |
case-08 | pass→pass | 4,379 | 2,636 | -40% | 1 | 1 | 0% | 887 | 3,134 | +253% | 0 | 0 | — |
case-09 | pass→pass | 8,265 | 11,098 | +34% | 1 | 1 | 0% | 1,642 | 4,236 | +158% | 0 | 0 | — |
case-10 | pass→pass | 5,507 | 7,643 | +39% | 1 | 1 | 0% | 1,077 | 3,388 | +215% | 0 | 0 | — |
case-11 | fail→pass | 9,770 | 11,133 | +14% | 1 | 1 | 0% | 1,737 | 4,504 | +159% | 0 | 0 | — |
case-12 | pass→pass | 9,664 | 5,153 | -47% | 1 | 1 | 0% | 1,931 | 3,469 | +80% | 0 | 0 | — |
case-13 | pass→pass | 7,160 | 4,199 | -41% | 1 | 1 | 0% | 1,361 | 3,279 | +141% | 0 | 0 | — |
case-14 | pass→pass | 8,067 | 7,378 | -9% | 1 | 1 | 0% | 1,336 | 3,533 | +164% | 0 | 0 | — |
case-15 | pass→pass | 2,429 | 1,997 | -18% | 1 | 1 | 0% | 369 | 2,902 | +686% | 0 | 0 | — |
case-16 | fail→pass | 8,244 | 2,347 | -72% | 1 | 1 | 0% | 1,306 | 2,804 | +115% | 0 | 0 | — |
case-17 | fail→pass | 11,033 | 1,899 | -83% | 1 | 1 | 0% | 1,768 | 2,810 | +59% | 0 | 0 | — |
case-18 | pass→pass | 13,396 | 5,761 | -57% | 1 | 1 | 0% | 1,835 | 3,514 | +91% | 0 | 0 | — |
case-19 | pass→pass | 11,156 | 7,087 | -36% | 1 | 1 | 0% | 2,004 | 3,726 | +86% | 0 | 0 | — |
case-20 | pass→pass | 11,360 | 11,843 | +4% | 1 | 1 | 0% | 2,342 | 4,787 | +104% | 0 | 0 | — |
case-21 | pass→pass | 13,144 | 10,846 | -17% | 1 | 1 | 0% | 2,643 | 4,717 | +78% | 0 | 0 | — |
case-22 | pass→pass | 16,204 | 13,358 | -18% | 1 | 1 | 0% | 2,637 | 5,102 | +93% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +18 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.