跳转至正文

如何用 11 步将 Web App 上架 App Store

如何借助 Capacitor 分 11 步将 Web App 上架 App Store 和 Google Play:原生壳、插件、账号、签名、测试、审核、Live Updates。

用 Capacitor 把 Web 应用变成 iOS 和 Android 应用

要把 Web 应用上架到 App Store 和 Google Play,需要用 Capacitor 把构建好的 Web 应用封装进原生项目,添加一些原生功能,创建 Apple 和 Google 开发者账号,签名并构建 iOS 和 Android 二进制文件,让真实用户测试,准备好商店页面并提交审核。现有 HTML、CSS 和 JavaScript 会继续在原生 WebView 中运行,因此无需重写应用。

以下是 11 个步骤,按避免等待的顺序排列,并附上适用于 Capacitor 8 的命令,以及 2026 年 10 月适用的商店规则。

准备工作

  • 可构建为静态文件的 Web 应用(React、Vue、Angular、Svelte、Next.js 静态导出、Nuxt generate、纯 HTML,或用 Lovable、Bolt 等 AI 构建器做的应用)。
  • Node.js 22 或更高版本(Capacitor 8 的要求),以及 Bun 或其他包管理器。
  • Android 构建需要 Android Studio。
  • iOS 构建需要 macOS 上的 Xcode 26;没有 Mac 的话就用云构建服务。
  • Apple 每年 99 美元,Google 一次性 25 美元。

合理的时间线

阶段 典型耗时 可以并行吗?
开发者账号注册 数小时(个人)到 2 周(需新申请 D-U-N-S 编号的组织) 是的,第一天就能开始
Capacitor 配置与首次真机运行 1 天
移动端打磨与原生功能 3 天到 3 周
签名与首次构建 1 天
Google Play 封闭测试(新个人账号) 至少 14 天,随后审核正式版发布权限 可以,使用 iOS TestFlight
应用商店详情页 1 到 2 天 是
App 审核 Apple 通常需要 1 到 2 天,Google 则从几小时到几天不等

第一步:今天开始注册开发者账号

账号验证是没法加速的一步,所以在开始写代码前先把它做完。

  • Apple 开发者计划: 每年 99 USD。个人需要开启双重认证,且 Apple Account 使用法定姓名。组织还需要 D-U-N-S 编号、公司网站以及该域名下的工作邮箱。
  • Google Play 控制台: 一次性支付 25 USD。组织用户需要 D-U-N-S 编号。会要求进行身份验证。

如果你以个人身份加入 Google Play,你的账号将受限于封闭测试规则(步骤 9)。完整流程如下: 如何创建 Apple 和 Google Play 开发者账号.

第二步:让 Web App 适配移动端

Capacitor 在 WebView 中运行你的应用。在浏览器标签页里没问题的事情,放到 App 里就会显得不对劲:

  • 静态构建输出。 Capacitor 从 App bundle 加载文件。服务端渲染不会在手机上运行。请使用你框架的静态输出(next build 配合 output: 'export', nuxt generate、Vite build)。API 的调用仍会像以前一样通过 HTTPS 发到你的后端。
  • 在 file origin 下也能正常工作的客户端路由。 请使用 history 路由(Capacitor 会从 https://localhost 在 Android 上, capacitor://localhost 在 iOS 上提供应用,因此可以正常工作),并确保深层 URL 能回退到 index.html.
  • CORS。 把 Capacitor 的 origin 加入 API 的允许 origin 列表: capacitor://localhost (iOS) 和 https://localhost (Android)。
  • 触摸,而非悬停。 移除仅靠悬停的菜单。点击目标至少为 44 x 44 pt。
  • 安全区域。 添加 viewport-fit=cover 添加到 viewport meta 标签,并为页眉和底部栏留出内边距 env(safe-area-inset-top) 以及 env(safe-area-inset-bottom).
  • 离线与弱网环境。 显示合适的状态,而不是白屏。审核人员会在不稳定的 Wi-Fi 下测试。
  • 不要出现“下载我们的 App”横幅 也不要有把用户引到你的网站完成核心任务的链接。
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />

第三步:添加 Capacitor

在你的 Web 项目根目录中:

bun add @capacitor/core
bun add -d @capacitor/cli
bunx cap init "My App" com.example.myapp --web-dir dist
bun add @capacitor/ios @capacitor/android
bun run build
bunx cap add ios
bunx cap add android

使用实际的输出文件夹 --web-dir: dist 针对 Vite, out 用于 Next.js 静态导出, .output/public 用于 Nuxt generate, build 用于 Create React App, dist/<project>/browser 用于 Angular。

Bundle ID(com.example.myapp) 一旦应用上架商店,此设置即为永久。请使用您控制的反向域名。

你的 capacitor.config.ts 现在看起来像这样:

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.example.myapp',
  appName: 'My App',
  webDir: 'dist',
};

export default config;

Capacitor 8 默认使用 Swift Package Manager 创建 iOS 项目,因此无需 CocoaPods。每次更改 Web code 时:

bun run build
bunx cap sync

运行:

bunx cap run ios
bunx cap run android

提交 ios/ 以及 android/ 文件夹。这些是您将编辑的源 code(权限、图标、签名)。更多背景信息,请参阅 使用 Capacitor 将 Web 应用转换为移动应用有多简单,如果您使用 AI 工具构建,我们的 Lovable 转移动端指南中描述的设置相同.

第 4 步:添加证明应用价值的原生功能

Apple 审核指南 4.2(最低功能)会拒绝只是把网站套个壳的 App。你不需要几十个原生功能,但 App 得像个 App。常见且实用的补充功能:

功能 插件
推送通知 @capacitor/push-notifications
原生 Google、Apple 和 Facebook 登录 @capgo/capacitor-social-login
Face ID / 指纹解锁 @capgo/capacitor-native-biometric
相机与相册 @capacitor/camera
应用内购买与订阅 @capgo/capacitor-native-purchases
原生分享面板 @capacitor/share
触感反馈 @capacitor/haptics
状态栏与启动页 @capacitor/status-bar, @capacitor/splash-screen
应用评分提示 @capgo/capacitor-in-app-review
Live Updates @capgo/capacitor-updater

示例:显示原生分享面板,而非“复制链接”按钮。

import { Share } from '@capacitor/share';
import { Capacitor } from '@capacitor/core';

export async function shareLink(url: string, title: string) {
  if (Capacitor.isNativePlatform()) {
    await Share.share({ title, url });
  } else {
    await navigator.clipboard.writeText(url);
  }
}

如果你销售数字内容或订阅,现在就要规划支付。Apple 和 Google 在大多数情况下要求数字商品使用其应用内购买系统。美国 App Store 的应用在 2025 年法院裁决后也可以链接到外部网页结账;其他地区有各自的规则。实物商品和服务(配送、打车)可以使用 Stripe 或任何支付服务商。详见 使用 Capacitor 实现应用内购买.

完整的 Capgo 插件目录位于 插件页面.

第 5 步:图标、启动页与权限说明

仅需两张源图即可生成所有尺寸的图标和启动页:

bun add -d @capacitor/assets
# assets/icon.png 1024x1024, assets/splash.png 2732x2732
bunx capacitor-assets generate

在 iOS 上,你使用的每项权限都必须在 ios/App/App/Info.plist中提供用途说明,否则在请求权限时应用会崩溃,且会被 Apple 拒绝:

<key>NSCameraUsageDescription</key>
<string>Take a photo of your receipt to attach it to an expense.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Choose receipt photos from your library.</string>

请写明具体理由。“此应用需要相机”会被拒绝。

在 Android 上,插件会自动把大多数权限添加到 manifest。请移除未使用的权限;Google 会要求你说明敏感权限的理由。

另外,请添加 隐私清单 (PrivacyInfo.xcprivacy)如果你的 code 使用了 required-reason API。请参阅 iOS 应用隐私清单指南.

步骤 6:配置签名

iOS。 你需要一个 Apple Distribution 证书(含私钥,通常导出为 .p12)以及对应 bundle ID 的 App Store Connect provisioning profile。Xcode 可以自动创建,你也可以自己创建,甚至无需 Mac。阅读 iOS 证书与 provisioning profile 详解; iOS 证书生成器 会在浏览器中处理 CSR 步骤。

Android。 创建一个 upload keystore 并做好备份。Google Play 使用 Play App Signing,最终的应用签名密钥由 Google 保管,你用自己的密钥为 upload 签名。

keytool -genkeypair -v -keystore upload-keystore.jks -alias upload \
  -keyalg RSA -keysize 2048 -validity 10000

或者使用 Android keystore 生成器.

第 7 步:构建发布版二进制文件

本地

iOS (需在装有 Xcode 26 的 Mac 上操作,自 2026 年 4 月起 App Store 上传必须使用该版本):

  1. bunx cap open ios
  2. 选择 应用 选择 target,设置版本号和构建号,并在 Signing &amp; Capabilities 中选择你的 Team。
  3. 选择 任何 iOS 设备 (arm64),然后 产品 &gt; 归档.
  4. 在 Organizer 中, Distribute App > App Store Connect > Upload.

Android:

bun run build
bunx cap sync android
cd android
./gradlew bundleRelease

AAB 文件位于 android/app/build/outputs/bundle/release/。配置 signingConfigs 中的 android/app/build.gradle 使用你的 keystore,并从环境变量中加载密码。

请确保 targetSdkVersion 是 36。自 2026 年 8 月 31 日起,Google Play 要求新应用和更新以 Android 16(API 36)为目标,这也是 Capacitor 8 的默认值。

在云端

如果你没有 Mac,或者希望构建能在 CI 中复现, Capgo 构建 在托管机器上构建两个平台的版本,并可直接上传到 TestFlight 和 Google Play:

bunx @capgo/cli@latest build credentials save --appId com.example.myapp --platform ios
bunx @capgo/cli@latest build credentials save --appId com.example.myapp --platform android
bunx @capgo/cli@latest build request com.example.myapp --platform ios --path .
bunx @capgo/cli@latest build request com.example.myapp --platform android --path .

凭据仅用于构建,不会存储在 Capgo 服务器上。请参阅 Capgo 构建文档.

第 8 步:分发给测试人员

在 Apple 或 Google 审核之前,先把构建装到真机上。

  • iOS:上传到 TestFlight。内部测试人员(最多 100 名团队成员)在构建处理完成后即可获取;外部测试人员(最多 10,000 名)则需经过简短的 Beta App Review。
  • Android:在 Play Console 中创建内部测试版本并分享加入链接。

测试注册与登录、沙盒环境下的支付、推送通知、离线行为、键盘遮挡输入框的情况,以及 Android 上的返回键行为。各选项详情如下: 如何向测试人员分发 iOS 和 Android 应用.

第 9 步:运行 Google Play 封闭测试(新个人账号)

如果您的 Play 账号是 2023 年 11 月 13 日之后创建的个人账号,那么必须先进行一次 至少有 12 名测试人员报名并连续参与 14 天的封闭测试。之后在 Play Console dashboard 中申请正式版权限,Google 通常会在两周内完成审核。

一旦有了可用的 Android build,就尽快开始。用 Google Group 作为测试人员名单,方便用户自行加入。在这 14 天里持续发布更新并收集反馈,因为 Google 会问您学到了什么。组织账号不受此限制。

第 10 步:准备商店详情并提交

两个商店都需要:应用名称、描述、符合尺寸要求的截图、图标、隐私政策 URL、隐私披露(Apple App Privacy 和 Google Data safety)、年龄分级问卷、支持联系方式,如果应用有登录功能还需提供演示账号。Google 还需要一张 1024 x 500 的特色图片。规格与限制: 如何准备 App Store 和 Google Play 的商店详情.

在 iOS 上提交: 在 App Store Connect 中创建版本,选择 TestFlight build,填写 App Review Information(演示账号、备注),然后点击 添加以供审核,然后 提交.

在 Android 上提交: 使用 AAB 创建正式版(或从测试轨道提升已测试的版本),完成所有 应用内容 声明,设置国家/地区,然后提交审核。

Web 应用最常遇到的拒绝原因:

  1. 4.2 最低功能要求:应用只是你的网站。请增加原生价值,并移除类似浏览器的 UI。
  2. 需要登录但未提供演示账号,或者账号无法使用。
  3. 缺乏注重隐私的登录选项 在 iOS 上提供 Google 或 Facebook 登录时,Guideline 4.8 要求提供限制数据收集的等效选项;通常选择 Sign in with Apple。
  4. 未提供注销账号功能 在应用内,当用户能够创建账户时。
  5. 通过 Stripe 进行数字购买 需要使用应用内购买的场景。
  6. iPad 布局错乱 因为项目默认支持 iPad。
  7. 权限描述缺失或模糊。

我们的 首次 App 审核指南 以及 iOS 应用提交指南 逐一详细说明。

第 11 步:无需等待审核即可发布更新

上线后,大部分改动仍会落在 Web code 中。与其每次修复都做一次新的商店构建,不如添加 Live Updates。Capgo 更新程序会从 Capgo 下载新的 Web bundle,并在下次启动时应用;如果新 bundle 启动失败,还会自动回滚。

bun add @capgo/capacitor-updater
bunx cap sync
bunx @capgo/cli@latest init

调用 notifyAppReady() 应用启动后,更新程序就能确认该 bundle 运行正常:

import { CapacitorUpdater } from '@capgo/capacitor-updater';

CapacitorUpdater.notifyAppReady();

之后,每次发布 Web code 都只需一条命令:

bun run build
bunx @capgo/cli@latest bundle upload --channel production

只要更新不改变应用的主要用途或绕过支付规则,两大应用商店都允许这种解释型 code。原生更改(新插件、新权限、Capacitor 升级)仍需走应用商店。了解更多请阅读 Capgo 实时更新 以及 updater 文档.

在首次向应用商店提交前添加该插件。它必须包含在用户安装的二进制包中,否则你的第一个 live update 要等到第二次商店发布后才能触达用户。

最后,实现自动化:通过 GitHub Actions 或 GitLab CI 在每次打 tag 时 build 并 upload,每次 merge 时推送 Live Updates 到 main,并将原生版本发布留给原生更改。

上线前检查清单

  • Apple 和 Google 账号已通过审核,协议已接受
  • App 支持离线运行或有明确的离线状态提示
  • 已处理安全区域、键盘及 Android 返回键
  • 具备至少几项 Web 端无法提供的原生功能
  • 图标、启动页、权限文案、隐私清单
  • 分发证书、App Store 描述文件及上传用 keystore 已备份
  • Android 目标 SDK 36,iOS 使用 Xcode 26 构建
  • 已在真机上完成 TestFlight 和 Play 内部测试
  • 已完成 Google Play 封闭测试(个人账号)
  • 两个商店的详情页均已完成,并添加了演示账号
  • 若支持用户注册,需提供应用内注销账号功能
  • 首个二进制包中已包含 Live Updates 插件

故障排除

启动时出现白屏。 webDir 指向了错误的文件夹,或者你忘了 bunx cap sync 构建后。请检查 ios/App/App/public 以及 android/app/src/main/assets/public 包含 index.html.

API 调用仅在 App 内失败。 CORS:允许 capacitor://localhost 以及 https://localhost。同时检查你没有调用 http:// URL,iOS 默认会拦截这些 URL。

刷新或 deep link 后路由 404。 使用可回退的路由器 index.html,或对旧版配置使用 hash 路由。

Xcode 签名错误。 请查看错误列表: iOS 证书与 provisioning profile 详解.

升级后 Gradle 构建失败。 Capacitor 8 需要 Android Studio Otter (2025.2.1) 或更高版本以及 JDK 21,详情请参阅 Capacitor 8 升级指南。其他 Gradle 错误请参阅 如何解决 Capacitor 中的 Android 构建错误.

目标 SDK 的 Google Play 上传被拒绝。 设置 targetSdkVersion = 36 中的 android/variables.gradle.

为 Capacitor 应用提供 Live Updates

当 Web 层出现线上 Bug 时,通过 Capgo 发布修复,而不用等 App Store 审核好几天。用户会在后台收到更新,原生变更则仍走正常审核流程。

博客最新动态

Capgo 为你提供打造真正专业的移动应用所需的最有价值的洞察。