App Store 发布
上线前检查、Archive 到 TestFlight、App 隐私标签,以及发布清单。
对一个 iOS 应用而言,"部署"就是发布到 App Store——没有服务器要部署、没有 Docker 镜像、 没有环境要晋级。本页是从本地 Xcode 构建到把构建版本送到审核员面前的端到端路径:先处理 模板的占位内容,再 Archive 并上传到 TestFlight,诚实地声明 App 隐私,然后按发布清单逐项 落实。
来源:模板中的 docs/app-store-release-overview.md。针对 Apple 沙盒的购买验证另见
购买测试;RevenueCat 仪表盘设置见
RevenueCat 设置。
前置条件
- 一个付费的 Apple Developer Program 账号(TestFlight 与沙盒购买测试都需要真机)。
- 一条 App Store Connect 应用记录,其 Bundle ID 与 Xcode、App Store Connect、 RevenueCat 一致。
- 在 App Store Connect 中已完成 付费应用协议、银行账户和税务表格(任何内购 能加载出来之前都必须完成)。
- 一个已配置 App Store 应用的 RevenueCat 项目。
模板默认的 bundle identifier 是:
com.soarstarter.SoarStarterSwift若你的应用使用不同的 Bundle ID,请替换每一处引用。
上线前检查:替换模板的占位内容
首次 Archive 之前,先过一遍模板附带的占位内容。它们对本地开发是安全默认值,但绝不能带上 App Store:
| 领域 | 需要修改的内容 | 位置 |
|---|---|---|
| Bundle ID | 你的反向 DNS 标识符,与 App Store Connect + RevenueCat 一致 | Xcode target,PRODUCT_BUNDLE_IDENTIFIER |
| 签名团队 | 你的 Release 分发团队 | Signing & Capabilities |
| 版本 / 构建号 | 每次上传前都递增构建号(1.0 (1) → 1.0 (2)) | Xcode target |
| 通用链接 | 用你的真实域名替换 applinks:example.com 占位符,并托管 AASA 文件 | 授权文件 + 深度链接 |
| 推送环境 | App Store 构建的 aps-environment = production | 授权文件 + 推送 |
| 法律 URL | 真实的 TERMS_URL / PRIVACY_URL / EULA_URL(同意门和审核都需要可用链接) | Secrets.xcconfig |
| 应用图标 + 启动图 | 替换占位的 AppIcon / 启动图资源 | Assets(主题) |
| 显示名称 | PRODUCT_NAME | Xcode target |
对 TestFlight 与 App Store 构建,REVENUECAT_IOS_KEY 必须是 App Store 应用的
公开 SDK 密钥(以 appl_ 开头)。RevenueCat 会故意让使用模拟商店密钥
(以 test_ 开头)的 Release 构建崩溃。见购买测试。
Archive 并上传到 TestFlight
准备 target
打开 SoarStarterSwift.xcodeproj。在 Signing & Capabilities 中选择你的 Release
团队,并确认 Bundle Identifier 与 App Store Connect 一致。递增构建号——每次上传都要
比上一次更高。
Archive
选择通用 iOS 设备(或一台真机)作为运行目标,然后执行 Product → Archive。用
xcodebuild 归档也可以,但 Organizer 是更顺滑的分发路径。
分发
在 Organizer 中选中归档 → Distribute App → App Store Connect → Upload, 按签名流程继续。
若 Xcode 报告 Upload Symbols Failed — The archive did not include a dSYM for Sentry.framework,上传仍会成功。它只影响该框架的崩溃符号化,不影响安装或购买——见
可观测性。
TestFlight
在 App Store Connect → 你的应用 → TestFlight 中,等待处理完成,若显示则解决 Missing Compliance(缺少合规信息),创建一个内部测试组,加入该构建,然后在真机上从 TestFlight 应用安装。
关于加密合规:若应用仅使用标准系统网络(HTTPS、Apple 登录、RevenueCat、Supabase、
Sentry、PostHog),请回答它不使用非豁免的专有加密。可在 Info.plist 中预声明:
<key>ITSAppUsesNonExemptEncryption</key>
<false/>App 隐私标签
审核要求你声明应用收集哪些数据。请对应到模板 SDK实际做的事——既不要多报也不要少报:
| SDK | 收集 | 说明 |
|---|---|---|
| Supabase | 账号数据(邮箱、用户 ID),以及你的表所存储的一切 | 与身份关联 |
| RevenueCat | 购买记录、一个设备/用户标识符 | 与身份关联 |
| PostHog | 产品分析 / 使用事件 | 受同意门控——同意门之前不发送任何数据;可禁用 |
| Sentry | 崩溃数据、诊断信息 | 用于应用功能 |
因为分析只在同意门之后启动,且 PostHog 与 Sentry 在没有密钥时都会 no-op,你的标签应
反映你的已配置构建——若你在没有 POSTHOG_API_KEY 的情况下发布,你就并未收集分析。
审核备注
审核会专门关注两件事,两者模板都已接好线:
- 应用内提供账号注销——账号与安全后面的
delete-accountEdge Function (示例功能)。Apple 要求任何提供注册的应用提供应用内 注销。请向审核员指明它。 - 同意门在用户同意前拦截跟踪——若被问及 App 隐私标签,可以提到它。
如果你的应用把功能锁在订阅之后,请提供一个演示账号或到达付费墙的说明,让审核员能够 测试它。
首次提交:内购
首个内购必须随一个新的应用版本一起提交。App Store Connect 会提示:
Your first in-app purchase must be submitted with a new app version.提交应用前,在应用版本页面上附上该内购。仅做 TestFlight 沙盒测试的话,一旦协议、税务、
银行、产品元数据和 RevenueCat 都正确,处于 Ready to Submit 状态的产品通常就够了。
发布清单
- Bundle ID / 签名团队 / 构建号已按 Release 设置。
-
REVENUECAT_IOS_KEY是appl_的 App Store 密钥,不是test_密钥。 -
REVENUECAT_PRO_ENTITLEMENT_ID与 RevenueCat 权益标识符完全一致(模板默认:pro)。 - 产品(
soar_starter_swift_pro_monthly/_pro_yearly/_lifetime)处于Ready to Submit、Cleared for Sale,并含价格 + 元数据 + 审核截图。 -
aps-environment=production,且 RevenueCat webhook 指向生产 Supabase 项目(Supabase 设置)。 -
applinks:授权使用你的真实域名并托管了 AASA 文件。 - 法律 URL、应用图标和显示名称是你自己的,而非占位符。
- 已确定更新门策略:
MIN_APP_VERSION/LATEST_APP_VERSION与APP_STORE_URL(App Store ID 出现后再填APP_STORE_URL)——见应用门。 - App 隐私标签与你的构建实际配置的 SDK 一致。
- 已验证审核员可用的应用内账号注销功能正常。
