29、发布上线:App Store审核、Google Play上架、灰度发布
说实话,WebRTC 移动端开发做到最后,最磨人的往往不是音视频逻辑,而是“上线”这一步。我自己就经历过:功能测了无数遍,一提交 App Store 却被拒,理由居然是“麦克风权限描述不够清晰”。嗯,这种坑踩过一次,你就再也不敢小看审核流程了。
这一章,我带你走一遍完整的发布流程。从打包签名,到过审,再到灰度放量。说白了,就是让你的 WebRTC 应用真正跑到用户手机里。
29.1 打包前的最后检查
别急着点“提交”。先花十分钟,把下面几项过一遍。我习惯列个清单,打勾一项再走下一步。
- 权限描述文案:iOS 的 Info.plist 里,
NSCameraUsageDescription和NSMicrophoneUsageDescription必须写清楚。比如“用于视频通话中的画面和声音传输”。别写“用于拍照”,审核员会直接拒。 - 后台模式:如果支持后台通话,记得在 Capabilities 里打开 Audio、AirPlay 和 Picture in Picture。我遇到过后台音频没勾,一按 Home 键通话就断,用户直接给一星差评。
- 日志开关:发布前关掉所有
RTCDefaultLogging和自定义日志输出。日志里可能带信令细节,属于隐私泄露风险。 - 版本号与构建号:iOS 用
CFBundleShortVersionString和CFBundleVersion,Android 用versionName和versionCode。确保递增,否则上架会报错。
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 命令检查一下二进制符号。
kAudioSessionProperty_OverrideCategoryMixWithOthers。后来换成了公开 API AVAudioSessionCategoryOptionMixWithOthers,才通过。
29.3 Google Play 上架:没那么严,但别大意
相比 App Store,Google Play 的审核宽松一些。但 2023 年后,Google 对权限和隐私的要求也变高了。尤其是 WebRTC 应用,经常需要后台定位或录音权限,容易触发“权限滥用”警告。
29.3.1 权限声明
在 AndroidManifest.xml 里,如果你声明了 RECORD_AUDIO 和 CAMERA,必须在 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。
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 支持“分阶段发布”,可以按百分比或国家/地区放量。我常用的策略是:
- 第一阶段:5% 的随机用户,持续 1 天
- 第二阶段:20% 的用户,持续 2 天
- 第三阶段:50% 的用户,持续 1 天
- 第四阶段:100% 全量
每个阶段之间,我会看 Crashlytics 和自定义事件。如果 ANR 率超过 0.1%,立刻回滚。
29.5 知识体系:发布上线的核心逻辑
下面这张图,是我自己总结的发布上线流程。你可以把它贴在墙上,每次提审前对照一遍。
29.6 发布后的第一件事
应用上线后,别急着庆祝。我习惯立刻做两件事:
- 自己下载生产包:从 App Store 或 Google Play 下载最新版本,完整跑一遍通话流程。因为有时候提审包和最终分发包会有差异(比如 Bitcode 重新编译)。
- 检查后台日志:看信令服务器的日志,确认新版本客户端的连接请求是否正常。如果发现大量“版本不匹配”错误,说明灰度比例没控制好,或者老用户没升级。
公众号:蓝海资料掘金营,微信deep3321