29、发布上线:App Store审核、Google Play上架、灰度发布

说实话,WebRTC 移动端开发做到最后,最磨人的往往不是音视频逻辑,而是“上线”这一步。我自己就经历过:功能测了无数遍,一提交 App Store 却被拒,理由居然是“麦克风权限描述不够清晰”。嗯,这种坑踩过一次,你就再也不敢小看审核流程了。

这一章,我带你走一遍完整的发布流程。从打包签名,到过审,再到灰度放量。说白了,就是让你的 WebRTC 应用真正跑到用户手机里。

29.1 打包前的最后检查

别急着点“提交”。先花十分钟,把下面几项过一遍。我习惯列个清单,打勾一项再走下一步。

  • 权限描述文案:iOS 的 Info.plist 里,NSCameraUsageDescriptionNSMicrophoneUsageDescription 必须写清楚。比如“用于视频通话中的画面和声音传输”。别写“用于拍照”,审核员会直接拒。
  • 后台模式:如果支持后台通话,记得在 Capabilities 里打开 Audio、AirPlay 和 Picture in Picture。我遇到过后台音频没勾,一按 Home 键通话就断,用户直接给一星差评。
  • 日志开关:发布前关掉所有 RTCDefaultLogging 和自定义日志输出。日志里可能带信令细节,属于隐私泄露风险。
  • 版本号与构建号:iOS 用 CFBundleShortVersionStringCFBundleVersion,Android 用 versionNameversionCode。确保递增,否则上架会报错。
我的习惯:每次提审前,我会用 Release 配置跑一遍“Archive”,然后导出 Development 包再测一轮。因为 Debug 和 Release 的优化级别不同,WebRTC 在 Release 下性能更好,但也可能暴露一些并发问题。

29.2 App Store 审核:那些年我踩过的坑

App Store 审核是出了名的“玄学”。但说白了,只要不碰红线,按规矩来,通过率很高。我总结了几条 WebRTC 应用最容易踩的点。

29.2.1 权限弹窗的时机

审核员会模拟首次打开 App。如果你一启动就弹“相机权限”,会被判定为“强制授权”。正确做法是:只在用户点击“开始通话”时才弹。我曾经因为提前弹窗被拒,后来改成点击按钮后调用 AVCaptureDevice.requestAccess,一次过。

29.2.2 通话质量的“假数据”

审核员在 Wi-Fi 环境下测试,网络很好。但你的 App 如果遇到弱网就黑屏或卡死,审核员会认为“功能不完整”。我建议在审核专用账号里,把码率调低一点,或者加一个“仅音频”模式兜底。

29.2.3 使用私有 API

WebRTC 本身是开源的,但有些第三方库可能调用了私有 API。比如某些音频处理库用了 AudioSession 的私有方法。审核工具会扫描 Mach-O 文件,一旦发现就拒绝。我的做法是:提审前用 nm 命令检查一下二进制符号。

避坑指南:我曾经集成了一个音频 3A 算法库,结果审核被拒,原因是调用了 kAudioSessionProperty_OverrideCategoryMixWithOthers。后来换成了公开 API AVAudioSessionCategoryOptionMixWithOthers,才通过。

29.3 Google Play 上架:没那么严,但别大意

相比 App Store,Google Play 的审核宽松一些。但 2023 年后,Google 对权限和隐私的要求也变高了。尤其是 WebRTC 应用,经常需要后台定位或录音权限,容易触发“权限滥用”警告。

29.3.1 权限声明

AndroidManifest.xml 里,如果你声明了 RECORD_AUDIOCAMERA,必须在 Play Console 里填写“权限用途说明”。我一般写:“用于实时音视频通话,仅在用户主动发起通话时请求。” 别写空话,Google 会人工抽查。

29.3.2 Target API 级别

Google 要求新应用必须 target API 33+。WebRTC 的 Android 库如果太旧,可能不支持。我建议用 Google 官方的 org.webrtc:google-webrtc:1.0.32006 以上版本,它已经适配了 Android 13 的权限模型。

29.3.3 64 位架构

从 2019 年起,Google Play 只接受 64 位版本。WebRTC 的 native 库必须包含 arm64-v8a 和 x86_64。我见过有人只打了 armeabi-v7a,结果上传时被直接拒绝。检查一下你的 build.gradle 里的 abiFilters

注意:如果你的 App 使用了 WebRTC 的屏幕共享功能,Android 14 要求必须使用 MediaProjection 的授权弹窗。否则会闪退。我在测试机上踩过这个坑,用户一共享屏幕就崩溃,后来加了 startActivityForResult 请求授权才解决。

29.4 灰度发布:小流量验证,大流量放心

全量发布是危险的。我习惯先放 5% 的用户,观察 24 小时。没问题再逐步扩大到 20%、50%、100%。灰度发布不是“偷懒”,而是对用户负责。

29.4.1 iOS 的 TestFlight

TestFlight 支持内部测试(最多 100 人)和外部测试(最多 10000 人)。我一般先内部测试,让团队和核心用户用两天。重点看:

  • 通话建立成功率(正常应 > 98%)
  • 音频路由切换(听筒/扬声器/蓝牙)
  • 前后台切换后的视频恢复

如果发现某个机型频繁断连,我会在 App Store Connect 里“暂停”该版本的发布,修完再提。

29.4.2 Android 的 Play Console 分阶段发布

Google Play 支持“分阶段发布”,可以按百分比或国家/地区放量。我常用的策略是:

  1. 第一阶段:5% 的随机用户,持续 1 天
  2. 第二阶段:20% 的用户,持续 2 天
  3. 第三阶段:50% 的用户,持续 1 天
  4. 第四阶段:100% 全量

每个阶段之间,我会看 Crashlytics 和自定义事件。如果 ANR 率超过 0.1%,立刻回滚。

我的经验:灰度发布时,一定要区分“新用户”和“老用户”。WebRTC 的升级经常涉及信令协议变化,老用户如果没更新,可能和新版本不兼容。我习惯在信令服务器上加一个版本号校验,低版本客户端自动提示升级。

29.5 知识体系:发布上线的核心逻辑

下面这张图,是我自己总结的发布上线流程。你可以把它贴在墙上,每次提审前对照一遍。

发布上线核心流程 1. 打包前检查 权限描述 · 后台模式 · 日志关闭 2. 平台提审 App Store / Google Play 3. 审核通过 等待发布 4. 灰度发布 5% → 20% → 50% → 100% 5. 监控 & 回滚 Crashlytics · ANR · 成功率 6. 全量发布 100% 用户可用 发现问题回滚 每个阶段都需要验证通话成功率 < 98% 则暂停发布

29.6 发布后的第一件事

应用上线后,别急着庆祝。我习惯立刻做两件事:

  • 自己下载生产包:从 App Store 或 Google Play 下载最新版本,完整跑一遍通话流程。因为有时候提审包和最终分发包会有差异(比如 Bitcode 重新编译)。
  • 检查后台日志:看信令服务器的日志,确认新版本客户端的连接请求是否正常。如果发现大量“版本不匹配”错误,说明灰度比例没控制好,或者老用户没升级。
一句话总结:发布上线不是终点,而是新版本生命周期的起点。灰度发布是你的安全网,监控是你的眼睛。别省这两步。

公众号:蓝海资料掘金营,微信deep3321