capacitor-app-store

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Publishing to App Stores

应用商店发布指南

Guide to submitting Capacitor apps to Apple App Store and Google Play Store.
Capacitor应用提交至Apple App Store和Google Play商店的详细指南。

When to Use This Skill

何时使用本指南

  • User is ready to publish app
  • User asks about app store submission
  • User needs app store screenshots
  • User has app rejection issues
  • User needs to update app listing
  • 用户准备发布应用
  • 用户询问应用商店提交相关问题
  • 用户需要制作应用商店截图
  • 用户遇到应用被拒问题
  • 用户需要更新应用商店列表信息

Pre-Submission Checklist

提交前检查清单

Universal Requirements

通用要求

  • App icon in all required sizes
  • Splash screen configured
  • App name and bundle ID set
  • Version and build numbers set
  • Privacy policy URL
  • Terms of service URL
  • Support email/URL
  • Age rating content questionnaire
  • App description (short and long)
  • Keywords/tags
  • Screenshots for all device sizes
  • Feature graphic (Android)
  • App preview video (optional)
  • 符合所有要求尺寸的应用图标
  • 已配置启动页
  • 已设置应用名称与Bundle ID
  • 已设置版本号与构建号
  • 隐私政策URL
  • 服务条款URL
  • 支持邮箱/URL
  • 已完成年龄分级内容问卷
  • 应用描述(简短版与完整版)
  • 关键词/标签
  • 适配所有设备尺寸的截图
  • 功能宣传图(Android)
  • 应用预览视频(可选)

iOS-Specific

iOS专属要求

  • Apple Developer Program membership ($99/year)
  • App Store Connect app created
  • Signing certificates and profiles
  • Info.plist usage descriptions
  • App Tracking Transparency (if applicable)
  • Sign in with Apple (if social login used)
  • Export compliance (encryption)
  • Apple开发者计划会员资格(年费99美元)
  • 已在App Store Connect创建应用
  • 签名证书与配置文件
  • Info.plist权限使用说明
  • App Tracking Transparency(如适用)
  • Sign in with Apple(如使用社交登录)
  • 出口合规(加密相关)

Android-Specific

Android专属要求

  • Google Play Developer account ($25 one-time)
  • App signed with release keystore
  • Target SDK level (API 34+)
  • 64-bit support
  • Permissions declared in manifest
  • Data safety form completed
  • Content rating questionnaire
  • Google Play开发者账号(一次性付费25美元)
  • 已使用发布密钥库签名应用
  • 目标SDK版本(API 34+)
  • 64位支持
  • 已在清单文件中声明权限
  • 已完成数据安全表单
  • 已完成内容分级问卷

App Store Configuration

应用商店配置

Version and Build Numbers

版本号与构建号

typescript
// capacitor.config.ts - Not stored here, just for reference

// iOS: Info.plist
// CFBundleShortVersionString = "1.2.3" (user-visible)
// CFBundleVersion = "45" (build number, increment each upload)

// Android: build.gradle
// versionName = "1.2.3" (user-visible)
// versionCode = 45 (must increment each upload)
typescript
// capacitor.config.ts - Not stored here, just for reference

// iOS: Info.plist
// CFBundleShortVersionString = "1.2.3" (user-visible)
// CFBundleVersion = "45" (build number, increment each upload)

// Android: build.gradle
// versionName = "1.2.3" (user-visible)
// versionCode = 45 (must increment each upload)

iOS Info.plist

iOS Info.plist

xml
<!-- ios/App/App/Info.plist -->
<key>CFBundleDisplayName</key>
<string>My App</string>

<key>CFBundleShortVersionString</key>
<string>1.0.0</string>

<key>CFBundleVersion</key>
<string>1</string>

<!-- Privacy descriptions - REQUIRED for permissions -->
<key>NSCameraUsageDescription</key>
<string>Take photos for your profile</string>

<key>NSPhotoLibraryUsageDescription</key>
<string>Select photos from your library</string>

<key>NSLocationWhenInUseUsageDescription</key>
<string>Find nearby locations</string>

<key>NSFaceIDUsageDescription</key>
<string>Secure login with Face ID</string>

<key>NSMicrophoneUsageDescription</key>
<string>Record voice messages</string>

<!-- App Tracking Transparency -->
<key>NSUserTrackingUsageDescription</key>
<string>Allow tracking for personalized ads</string>

<!-- Export compliance -->
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
xml
<!-- ios/App/App/Info.plist -->
<key>CFBundleDisplayName</key>
<string>My App</string>

<key>CFBundleShortVersionString</key>
<string>1.0.0</string>

<key>CFBundleVersion</key>
<string>1</string>

<!-- Privacy descriptions - REQUIRED for permissions -->
<key>NSCameraUsageDescription</key>
<string>Take photos for your profile</string>

<key>NSPhotoLibraryUsageDescription</key>
<string>Select photos from your library</string>

<key>NSLocationWhenInUseUsageDescription</key>
<string>Find nearby locations</string>

<key>NSFaceIDUsageDescription</key>
<string>Secure login with Face ID</string>

<key>NSMicrophoneUsageDescription</key>
<string>Record voice messages</string>

<!-- App Tracking Transparency -->
<key>NSUserTrackingUsageDescription</key>
<string>Allow tracking for personalized ads</string>

<!-- Export compliance -->
<key>ITSAppUsesNonExemptEncryption</key>
<false/>

Android build.gradle

Android build.gradle

groovy
// android/app/build.gradle
android {
    defaultConfig {
        applicationId "com.yourcompany.yourapp"
        minSdkVersion 22
        targetSdkVersion 34
        versionCode 1
        versionName "1.0.0"

        // 64-bit support
        ndk {
            abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
        }
    }

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    bundle {
        language {
            enableSplit = true
        }
        density {
            enableSplit = true
        }
        abi {
            enableSplit = true
        }
    }
}
groovy
// android/app/build.gradle
android {
    defaultConfig {
        applicationId "com.yourcompany.yourapp"
        minSdkVersion 22
        targetSdkVersion 34
        versionCode 1
        versionName "1.0.0"

        // 64-bit support
        ndk {
            abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
        }
    }

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    bundle {
        language {
            enableSplit = true
        }
        density {
            enableSplit = true
        }
        abi {
            enableSplit = true
        }
    }
}

App Icons

应用图标

iOS App Icons

iOS应用图标

Required sizes (place in Assets.xcassets):
SizeScaleUsage
20pt2x, 3xNotification
29pt2x, 3xSettings
40pt2x, 3xSpotlight
60pt2x, 3xApp Icon
76pt1x, 2xiPad
83.5pt2xiPad Pro
1024pt1xApp Store
所需尺寸(放置于Assets.xcassets):
尺寸缩放比例用途
20pt2x, 3x通知图标
29pt2x, 3x设置图标
40pt2x, 3x搜索图标
60pt2x, 3x应用主图标
76pt1x, 2xiPad图标
83.5pt2xiPad Pro图标
1024pt1xApp Store展示图标

Android App Icons

Android应用图标

Required sizes (place in res/mipmap-*):
DensitySizeFolder
mdpi48x48mipmap-mdpi
hdpi72x72mipmap-hdpi
xhdpi96x96mipmap-xhdpi
xxhdpi144x144mipmap-xxhdpi
xxxhdpi192x192mipmap-xxxhdpi
Also needed:
  • Adaptive icon (foreground + background layers)
  • Play Store icon: 512x512
所需尺寸(放置于res/mipmap-*):
密度尺寸文件夹
mdpi48x48mipmap-mdpi
hdpi72x72mipmap-hdpi
xhdpi96x96mipmap-xhdpi
xxhdpi144x144mipmap-xxhdpi
xxxhdpi192x192mipmap-xxxhdpi
还需准备:
  • 自适应图标(前景层+背景层)
  • Play Store图标:512x512

Generate Icons

生成图标

bash
undefined
bash
undefined

Use capacitor-assets

Use capacitor-assets

bun add -D @capacitor/assets bunx capacitor-assets generate --iconBackgroundColor '#ffffff'
undefined
bun add -D @capacitor/assets bunx capacitor-assets generate --iconBackgroundColor '#ffffff'
undefined

Screenshots

应用截图

iOS Screenshot Sizes

iOS截图尺寸

DeviceSizeRequired
iPhone 6.7"1290x2796Yes
iPhone 6.5"1284x2778Yes
iPhone 5.5"1242x2208Yes
iPad Pro 12.9"2048x2732If supporting iPad
iPad Pro 11"1668x2388If supporting iPad
设备尺寸是否必填
iPhone 6.7"1290x2796
iPhone 6.5"1284x2778
iPhone 5.5"1242x2208
iPad Pro 12.9"2048x2732若支持iPad则必填
iPad Pro 11"1668x2388若支持iPad则必填

Android Screenshot Sizes

Android截图尺寸

TypeSizeRequired
Phone1080x1920 to 1080x2400Yes (2-8)
7" Tablet1200x1920If supporting
10" Tablet1600x2560If supporting
类型尺寸是否必填
手机1080x1920 至 1080x2400是(2-8张)
7"平板1200x1920若支持则必填
10"平板1600x2560若支持则必填

Feature Graphic (Android)

Android功能宣传图

  • Size: 1024x500
  • Required for Play Store listing
  • 尺寸:1024x500
  • Play Store列表必填

Generating Screenshots

生成截图

typescript
// Use Playwright for automated screenshots
import { test } from '@playwright/test';

const devices = [
  { name: 'iPhone 14 Pro Max', viewport: { width: 430, height: 932 } },
  { name: 'iPhone 14', viewport: { width: 390, height: 844 } },
  { name: 'Pixel 7', viewport: { width: 412, height: 915 } },
];

test('generate screenshots', async ({ page }) => {
  for (const device of devices) {
    await page.setViewportSize(device.viewport);

    // Screenshot 1: Home
    await page.goto('/');
    await page.screenshot({
      path: `screenshots/${device.name}-home.png`,
      fullPage: false,
    });

    // Screenshot 2: Feature
    await page.goto('/feature');
    await page.screenshot({
      path: `screenshots/${device.name}-feature.png`,
    });
  }
});
typescript
// Use Playwright for automated screenshots
import { test } from '@playwright/test';

const devices = [
  { name: 'iPhone 14 Pro Max', viewport: { width: 430, height: 932 } },
  { name: 'iPhone 14', viewport: { width: 390, height: 844 } },
  { name: 'Pixel 7', viewport: { width: 412, height: 915 } },
];

test('generate screenshots', async ({ page }) => {
  for (const device of devices) {
    await page.setViewportSize(device.viewport);

    // Screenshot 1: Home
    await page.goto('/');
    await page.screenshot({
      path: `screenshots/${device.name}-home.png`,
      fullPage: false,
    });

    // Screenshot 2: Feature
    await page.goto('/feature');
    await page.screenshot({
      path: `screenshots/${device.name}-feature.png`,
    });
  }
});

App Store Connect Submission

App Store Connect提交流程

1. Create App

1. 创建应用

  1. Go to https://appstoreconnect.apple.com
  2. My Apps > + > New App
  3. Fill in:
    • Platform: iOS
    • Name: Your App Name
    • Primary Language
    • Bundle ID
    • SKU (unique identifier)
  1. 访问 https://appstoreconnect.apple.com
  2. 我的应用 > + > 新建应用
  3. 填写信息:
    • 平台:iOS
    • 名称:您的应用名称
    • 主要语言
    • Bundle ID
    • SKU(唯一标识符)

2. App Information

2. 应用信息

  • Category (primary and secondary)
  • Content Rights
  • Age Rating (complete questionnaire)
  • 分类(主分类与副分类)
  • 内容权限
  • 年龄分级(完成问卷)

3. Pricing and Availability

3. 定价与可用性

  • Price (Free or paid tier)
  • Availability (countries)
  • 价格(免费或付费档位)
  • 可用地区

4. App Privacy

4. 应用隐私

  • Privacy Policy URL (required)
  • Data collection types:
    • Contact Info
    • Health & Fitness
    • Financial Info
    • Location
    • Identifiers
    • Usage Data
    • etc.
  • 隐私政策URL(必填)
  • 数据收集类型:
    • 联系信息
    • 健康与健身
    • 财务信息
    • 位置信息
    • 标识符
    • 使用数据

5. Version Information

5. 版本信息

  • Screenshots (all sizes)
  • Promotional Text (170 chars)
  • Description (4000 chars)
  • Keywords (100 chars, comma-separated)
  • Support URL
  • Marketing URL (optional)
  • What's New (for updates)
  • 截图(所有尺寸)
  • 宣传文本(170字符)
  • 描述(4000字符)
  • 关键词(100字符,逗号分隔)
  • 支持URL
  • 营销URL(可选)
  • 新功能介绍(更新时填写)

6. Build Upload

6. 构建版本上传

bash
undefined
bash
undefined

Using Xcode

使用Xcode

Product > Archive > Distribute App > App Store Connect

产品 > 归档 > 分发应用 > App Store Connect

Using Fastlane

使用Fastlane

fastlane ios release
fastlane ios release

Using xcrun

使用xcrun

xcrun altool --upload-app --type ios --file App.ipa
--apiKey KEY_ID --apiIssuer ISSUER_ID
undefined
xcrun altool --upload-app --type ios --file App.ipa
--apiKey KEY_ID --apiIssuer ISSUER_ID
undefined

7. Submit for Review

7. 提交审核

  • Answer export compliance questions
  • Add notes for reviewer (if needed)
  • Submit
  • 回答出口合规问题
  • 如需可添加审核备注
  • 提交审核

Google Play Console Submission

Google Play Console提交流程

1. Create App

1. 创建应用

  1. Go to https://play.google.com/console
  2. All apps > Create app
  3. Fill in:
    • App name
    • Default language
    • App or game
    • Free or paid
  1. 访问 https://play.google.com/console
  2. 所有应用 > 创建应用
  3. 填写信息:
    • 应用名称
    • 默认语言
    • 应用或游戏
    • 免费或付费

2. Store Listing

2. 商店列表

  • Short description (80 chars)
  • Full description (4000 chars)
  • Screenshots (2-8 per device type)
  • Feature graphic (1024x500)
  • App icon (512x512)
  • Video URL (optional, YouTube)
  • 简短描述(80字符)
  • 完整描述(4000字符)
  • 截图(每种设备类型2-8张)
  • 功能宣传图(1024x500)
  • 应用图标(512x512)
  • 视频URL(可选,YouTube链接)

3. Content Rating

3. 内容分级

Complete the questionnaire for IARC rating
完成IARC分级问卷

4. Target Audience

4. 目标受众

  • Target age group
  • Ads declaration
  • 目标年龄组
  • 广告声明

5. Data Safety

5. 数据安全

  • Data collection
  • Data sharing
  • Security practices
  • Data deletion request handling
  • 数据收集
  • 数据共享
  • 安全措施
  • 数据删除请求处理

6. App Content

6. 应用内容

  • Ads (yes/no)
  • App category
  • Contact details
  • Privacy policy
  • 是否包含广告
  • 应用分类
  • 联系详情
  • 隐私政策

7. Release

7. 发布应用

bash
undefined
bash
undefined

Build AAB (required for new apps)

构建AAB(新应用必填)

cd android && ./gradlew bundleRelease
cd android && ./gradlew bundleRelease

Upload via Play Console or API

通过Play Console或API上传

Production > Create new release > Upload AAB

生产版 > 创建新版本 > 上传AAB

undefined
undefined

Release Tracks

发布渠道

TrackPurpose
Internal testingUp to 100 testers, instant
Closed testingInvite-only, review
Open testingPublic beta
ProductionFull release
渠道用途
内部测试最多100名测试人员,即时可用
封闭测试邀请制,需审核
公开测试公开Beta版
生产版正式发布

Common Rejection Reasons

常见被拒原因

iOS Rejections

iOS被拒原因

ReasonSolution
CrashesTest on real devices, fix bugs
Broken linksVerify all URLs work
Incomplete metadataFill all required fields
Missing privacy infoComplete App Privacy section
Login issuesProvide demo account
Guideline 4.2 (Minimum Functionality)Add meaningful features
Guideline 5.1.1 (Data Collection)Justify data usage
原因解决方案
应用崩溃在真实设备上测试,修复Bug
链接失效验证所有URL可正常访问
元数据不完整填写所有必填字段
隐私信息缺失完成应用隐私部分填写
登录问题提供测试账号
准则4.2(最低功能要求)添加有意义的功能
准则5.1.1(数据收集)说明数据使用理由

Android Rejections

Android被拒原因

ReasonSolution
Crashes/ANRsFix stability issues
Policy violationReview Play policies
Deceptive behaviorBe transparent about features
Sensitive permissionsJustify in-app
Target SDK too lowUpdate to API 34+
原因解决方案
崩溃/应用无响应修复稳定性问题
违反政策查阅Play商店政策
误导性行为透明展示功能
敏感权限在应用内说明权限用途
目标SDK版本过低更新至API 34+

Updates and Versioning

更新与版本控制

Version Incrementing

版本号递增

bash
undefined
bash
undefined

Increment patch (1.0.0 -> 1.0.1)

递增修订号(1.0.0 -> 1.0.1)

bun version patch
bun version patch

Increment minor (1.0.0 -> 1.1.0)

递增次版本号(1.0.0 -> 1.1.0)

bun version minor
bun version minor

Increment major (1.0.0 -> 2.0.0)

递增主版本号(1.0.0 -> 2.0.0)

bun version major
undefined
bun version major
undefined

Phased Rollout

分阶段发布

iOS:
  • Enable phased release in App Store Connect
  • 7-day gradual rollout (1%, 2%, 5%, 10%, 20%, 50%, 100%)
Android:
  • Set rollout percentage in release
  • Monitor crash rate before increasing
iOS:
  • 在App Store Connect启用分阶段发布
  • 7天逐步发布(1%, 2%, 5%, 10%, 20%, 50%, 100%)
Android:
  • 在发布时设置发布比例
  • 提升比例前监控崩溃率

Resources

参考资源