要将 Web 应用程序发布到 App Store 和 Google Play,需要将构建的 Web 应用程序包装在一个原生项目中,使用 Capacitor,添加一些原生功能,创建 Apple 和 Google 开发者帐户,签署并构建 iOS 和 Android 二进制文件,测试它们使用真实用户,准备商店列表并提交审核。您的现有 HTML、CSS 和 JavaScript 将在原生 WebView 中继续运行,因此您不需要重写应用程序。
以下是 11 步骤的顺序,避免等待,带有命令 Capacitor 8 和适用于 2026 年 10 月的商店规则。
您需要的内容
- 一个可以静态文件构建的 Web 应用程序(React、Vue、Angular、Svelte、Next.js 静态导出、Nuxt 生成、纯 HTML 或使用 Lovable 或 Bolt 等 AI 构建器创建的应用程序)。
- Node.js 22 或更高版本(Capacitor 8 要求)和 Bun 或另一个包管理器。
- Android Studio 用于 Android 构建。
- Xcode 26 在 macOS 上用于 iOS 构建,或者如果您没有 Mac,则使用云构建服务。
- 每年99美元(苹果)和25美元一次(谷歌)
现实时间表
| 阶段 | 典型时间 | 是否可以并行? |
|---|---|---|
| 开发者账户注册 | 1-2周(个人)至2周(新D-U-N-S组织) | 是,从第一天开始 |
| Capacitor设置和首次设备运行 | 1天 | |
| 移动优化和原生功能 | 3天至3周 | |
| 签名和首次构建 | 1 天 | |
| Google Play 闭测 (新个人账户) | 至少 14 天,之后生产访问审查 | 是的,使用 iOS TestFlight |
| 商店列表 | 1 到 2 天 | 是 |
| 比较 | 应用程序审查 |
苹果通常 1 到 2 天,谷歌从几小时到几天
步骤 1:立即开始开发者账户注册过程
- Apple Developer Program: 99 USD 每年。个人需要 Apple 帐户,具有两因素身份验证和他们的法律姓名。组织也需要 D-U-N-S 号,公司网站和工作电子邮件在该域名。
- Google Play Console: 25 USD 一次。组织需要 D-U-N-S 号。预计 ID 验证。
如果您在 Google Play 注册为个人帐户,则您的帐户将受闭合测试规则 (第 9 步) 的约束。完整教程: 如何创建 Apple 和 Google Play 开发者帐户.
步骤 2:使 Web 应用程序准备好手机
Capacitor 在 WebView 中运行您的应用。浏览器标签中一切都正常,但在应用中却感到不适。
- __CAPGO_KEEP_0__ 在 WebView 中运行您的应用程序。浏览器标签中一切都很好,但在应用程序中却感到不适的东西: Capacitor 从应用程序包中加载文件。 服务器端渲染不会在手机上运行。 使用您的框架的静态输出(例如 Capacitor 的 `loadUrl` 或 `loadUrlAsync`)来呈现您的应用程序。
next buildwithoutput: 'export',nuxt generate,Vitebuild. API 调用将继续使用 HTTPS 与您的后端通信。 - 支持从文件源起始的客户端路由。 使用历史路由(Capacitor 将应用程序从文件源服务),并确保深度 URL 回退到 CORS。
https://localhost将 __CAPGO_KEEP_0__ 源添加到您的 __CAPGO_KEEP_1__ 允许的源中:capacitor://localhost(iOS) 和index.html. - (Android)。 在您的 API 中,添加以下 Capacitor 的来源:
capacitor://localhost(iOS)https://localhost安全区域。 - iOS 和 Android 上都支持。
- 确保深 URL 回退到 CORS。 添加
viewport-fit=cover到视口元标签并用填充头部和底部栏env(safe-area-inset-top)和env(safe-area-inset-bottom). - 离线和慢速网络 显示合适的状态而不是空白屏幕。审阅者在Wi-Fi不稳定时测试
- 没有“下载我们的应用程序”的横幅 没有将用户发送到您的网站以执行核心任务的链接
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
步骤 3:添加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.
包 ID (com.example.myapp) 一旦应用发布到商店中,包 ID 就是永久的。使用您控制的反向域名。
您的 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/ folders。它们是源code您将编辑(权限、图标、签名)。有关更多背景,请参见 How easy it is to turn a web app into a mobile app with Capacitor,如果您使用了 AI 工具构建应用,我们 Make a web app into a mobile app.
步骤 4:添加本机功能以证明应用的价值
苹果指南 4.2(最小功能性)拒绝将网站裹在壳子里的应用。您不需要 dozens 个原生功能,但您需要让应用像应用一样运行。常见、有用的添加:
| 功能 | 插件 |
|---|---|
| 推送通知 | @capacitor/push-notifications |
| 原生 Google、Apple 和 Facebook 登录 | @capgo/capacitor-social-login |
| 面部识别/指纹解锁 | @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 |
| 实时更新 | @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);
}
}
示例:显示原生分享面板而不是“复制链接”按钮。 在应用内购买中使用Capacitor.
The full catalog of Capgo plugins is on the Capgo website. 完整的__CAPGO_KEEP_0__ 插件目录在.
插件页面
步骤 5:图标、启动屏幕和权限字符串
bun add -d @capacitor/assets
# assets/icon.png 1024x1024, assets/splash.png 2732x2732
bunx capacitor-assets generate
On iOS,使用的每个权限都需要在 ios/App/App/Info.plist或当它要求时,应用程序会崩溃,苹果会拒绝它:
<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 上,插件会将大多数权限添加到清单中。 移除您不使用的权限; Google 会要求您为敏感权限提供理由。
也添加一个 隐私清单 (PrivacyInfo.xcprivacy),如果您的 code 使用需要原因的 API。 请参阅 privacy manifest guide for Capacitor.
第 6 步:设置签名
iOS。 您需要一个苹果分发证书(带有其私钥,通常以 .p12)和一个适用于您的包 ID 的 App Store Connect 配置文件。 Xcode 可以自动创建它们,或者您可以自己创建它们,即使没有 Mac。 请阅读 iOS 证书和配置文件简介; iOS 证书生成器 在浏览器中处理 CSR 步骤。
Android。 创建一个上传密钥库并备份它。Google Play 使用 Play App Signing,因此 Google 保留了最终的应用签名密钥,而您使用自己的密钥签名上传。
keytool -genkeypair -v -keystore upload-keystore.jks -alias upload \
-keyalg RSA -keysize 2048 -validity 10000
或使用 Android 密钥库生成器.
第 7 步:构建发布二进制文件
本地
iOS (在一台 Mac 上使用 Xcode 26,自 2026 年 4 月起 App Store 上传需要:)
bunx cap open ios- 选择目标 App 选择目标,设置版本和构建号,选择您的团队在 Signing & Capabilities 中。
- 选择 任何 iOS 设备 (arm64),然后 产品 > 归档.
- 在 Organizer 中 Distribute App > App Store Connect > 上传.
Android:
bun run build
bunx cap sync android
cd android
./gradlew bundleRelease
AAB 位于 . Configure android/app/build/outputs/bundle/release/. Configure signingConfigs 在 android/app/build.gradle 使用您的keystore,加载环境变量中的密码。
确保 targetSdkVersion 是36。自2026年8月31日起,Google Play要求新应用和更新目标Android 16(API 36),这是Capacitor 8的默认值。
在云端
如果您没有Mac,或者您想从CI中获得可重复的构建 Capgo 构建 在云端
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 服务器上存储。请参阅.
__CAPGO_KEEP_0__ Build 文档
步骤8:向测试者分发
- iOS: 上传到 TestFlight。内部测试者(最多 100 名团队成员)在处理后立即获得;外部测试者(最多 10,000 名)在短暂的 Beta App Review 后获得。
- Android: 在 Play Console 中创建内部测试发布并分享选入链接。
Test sign-up and login, payments in sandbox, push notifications, offline behavior, the keyboard covering inputs, and back-button behavior on Android。每个选项的详细信息: 如何将 iOS 和 Android 应用程序分发给测试者.
第 9 步:运行 Google Play 的封闭测试(新个人账户)
context 闭式测试至少需要12名测试者参与,持续14天如果您的 Play 账户是 2023 年 11 月 13 日之后创建的个人账户,则无法在没有运行至少 12 名测试者在 14 天内同意的封闭测试之前发布到生产环境。
然后您在 Play Console 控制台中申请生产访问权限,Google 通常在一周内审查。
步骤 10:准备商店列表并提交
您需要为两家商店准备:应用名称、描述、符合要求的截图、图标、隐私政策URL、隐私披露(Apple App隐私和Google数据安全)、年龄评级问卷、支持联系方式,以及如果应用有登录功能,则需要一个演示账号。Google还需要一个1024 x 500的特征图。规范和限制: 如何准备App Store和Google Play的列表.
在iOS上提交: 在App Store Connect中,创建版本,选择TestFlight构建,填写App Review信息(演示账号、备注),并点击 添加到审查然后 提交.
在Android上提交: 创建一个生产版本(AAB)或将测试版本从测试轨道推出,完成所有 应用内容 声明,设置国家,并发送审查。
常见的拒绝理由:
- 4.2 最小功能: 应用程序只是您的网站。添加本机值并删除浏览器样式的UI。
- 需要登录但没有演示账户, 或账户无法正常工作。
- 没有隐私保护的登录选项 当您在iOS上提供Google或Facebook登录时。指南4.8要求一个等效的选项来限制数据收集;使用Apple登录是常见的选择。
- 没有账户删除功能 在应用程序内部,当用户可以创建账户时。
- 通过Stripe进行数字购买 在需要应用程序内购买时。
- iPad布局破裂 因为项目默认支持iPad。
- 缺失或模糊的权限字符串。
我们的 首次应用审查指南 和 iOS应用提交指南 逐步检查每个步骤。
第11步:不等待审查就将更新推送
发布后,大部分更改仍然在webcode上。为了避免为每个修复创建新的商店构建,使用实时更新。Capgo更新器从Capgo下载新的web包并在下一次启动时应用它们,自动回滚如果新包无法启动。
bun add @capgo/capacitor-updater
bunx cap sync
bunx @capgo/cli@latest init
Call notifyAppReady() 然后,每个web__CAPGO_KEEP_0__的发布都是一个命令:
import { CapacitorUpdater } from '@capgo/capacitor-updater';
CapacitorUpdater.notifyAppReady();
Then each release of web code is one command:
bun run build
bunx @capgo/cli@latest bundle upload --channel production
Both stores allow this for interpreted code as long as the update does not change the app’s main purpose or bypass their payment rules. Native changes (new plugins, new permissions, Capacitor upgrades) still go through the stores. Read more on Capgo 实时更新 和 更新器文档.
在第一次提交应用商店之前添加插件。它必须在用户安装的二进制文件中,否则您的第一次 live update 只能在第二次应用商店发布后才能到达用户。
最后,自动化:在 GitHub Actions 或 GitLab CI 上构建和上传,每次合并到 main,并保留原生版本用于原生更改。
预发布检查表
- 苹果和谷歌账户已批准,协议已接受
- 应用程序在离线状态下正常工作或显示清晰的离线状态
- 安全区域,键盘和 Android 返回按钮处理
- 至少有几个原生功能,网站无法提供的功能
- 图标,启动画面,权限字符串,隐私清单
- 发布证书,App Store 配置文件,上传备份的.keystore
- 目标SDK 36 在 Android 上,使用 Xcode 26 在 iOS 上构建
- TestFlight 和 Play 内部测试已在真实设备上完成
- Google Play closed test 已完成(个人账户)
- 两家商店的列表已完成,添加了演示账户
- 用户可以注册后删除应用内账户
- Live updates 插件已包含在第一个二进制文件中
故障排除
启动时出现白屏。 webDir 可能是指向错误的文件夹或您忘记了 bunx cap sync 检查 ios/App/App/public 并 android/app/src/main/assets/public 包含 index.html.
API调用失败仅在应用中。 CORS:允许 capacitor://localhost 和 https://localhostURLs,iOS默认会阻止。 http:// 路由404后刷新或深度链接。
使用路由器回退到 或哈希路由 index.htmlXcode签名错误。
查看错误列表在 iOS证书和分发配置文件解释 iOS证书和分发配置文件.
Gradle 构建失败后升级。 Capacitor 8 需要 Android Studio Otter (2025.2.1) 或更高版本,以及 JDK 21,详见升级指南。 Capacitor 8 升级指南。其他 Gradle 错误,请参见 如何解决 Android 构建错误的 Capacitor.
Google Play 上传被拒绝,目标是 SDK。 设置 targetSdkVersion = 36 在 android/variables.gradle.