Guideline 2.5.4 被拒:后台模式怎么处理
作者:Mehdi Azizi
发布于 ,9分钟
Apple 会拒绝声明了却没有功能使用的后台模式。删掉这个键,或者把声音、定位、通话功能演示给审核员看。
Guideline 2.5.4 规定,后台模式只能用于它们的预定用途:音频、定位、VoIP 通话、任务收尾、本地通知。如果你的 Info.plist 声明了其中某个模式,而审核员找不到任何需要它的功能,就会被拒。没有功能用到就删掉这个键,否则就让审核员在三十秒内看到这个功能。
我用 Expo 发布自己的 iOS 应用。Solys 是我做的小游戏闹钟,它声明了 audio 模式:我删过一次,后来又因为另一个原因加了回来。这篇指南依据的是 Apple 的原文、其他开发者公开的被拒案例,以及我自己的项目。想了解各种被拒原因的全貌,可以看Apple 为什么拒绝你的应用。
Guideline 2.5.4 说了什么?
这条规则只有一句话,位于 App Review Guidelines 第 2 节「Performance」的 2.5「Software Requirements」部分:“Multitasking apps may only use background services for their intended purposes: VoIP, audio playback, location, task completion, local notifications, etc.”
说白了:后台服务只能用来做它本来该做的事。所以被拒标题是“Guideline 2.5.4 - Performance - Software Requirements”。
默认情况下,应用进入后台就会被挂起。想继续运行,就要在 Info.plist 的 UIBackgroundModes 键里声明一个或多个模式。Apple 关于后台模式的文档要求出于电量考虑谨慎使用,有其他方案时优先用其他方案。每声明一个模式,就是一个审核员可以核实的承诺。
后台模式及其预定用途
| 模式 | 键 | 预定用途 |
|---|---|---|
| 音频、AirPlay、画中画 | audio | 后台可听见的声音 |
| 定位 | location | 持续定位 |
| VoIP | voip | 配合 CallKit 的通话 |
| 后台获取 | fetch | 定期获取网络内容 |
| 后台处理 | processing | 计划任务 |
| 远程通知 | remote-notification | 推送新内容 |
这张表总结自 Apple 的文档页面。在论坛公开的被拒案例里,最常出现的是 audio、location 和 voip。
2.5.4 被拒消息是什么意思?
消息里会点名出问题的模式。下面是开发者在 Apple 论坛上公开的两个例子:
- 音频:“Your app still declares support for audio in the UIBackgroundModes key in your Info.plist but did not include features that require persistent audio.” 后文说明,
audio键是给在后台播放可听内容的应用用的,比如音乐播放器。它给出两条出路:加上这类内容,或者删掉这个键(论坛帖子)。 - 定位:在一个 2024 年 12 月的帖子里,Apple 除了员工追踪之外,没找到任何需要持续定位的功能,并表示仅这一个用途并不合适。
我的理解是:审核员不看你的代码,他找的是功能。 他得能启动这个功能,把应用切到后台,然后确认它还在运行。
反过来的情况也有。在一个 2026 年 5 月的帖子里,一款朗读应用确实在用 audio 模式,却被拒了好几次:审核员没能触发声音。另一位开发者在帖子里说,他认为是附上一段视频才让他的问题得到解决。这只是个人经验,不是 Apple 的规定。
你没加过这个键,它是从哪来的?
在 Expo 里,Info.plist 是由配置插件在 prebuild 时填写的。所以一个后台模式可能在你没决定的情况下就进了你的二进制文件。
expo-audio 插件的默认设置
expo-audio 文档写得很清楚:enableBackgroundPlayback 选项默认是 true,在 iOS 上会添加 audio 模式。所以只要用简写形式 "expo-audio" 声明插件,就等于声明了这个模式。
我在 TradaZen 首次提交前复查时就发现了这个问题:前台只有简短的界面音效,但插件是用简写形式声明的。修复只需改 app.json:
{
"expo": {
"plugins": [["expo-audio", { "enableBackgroundPlayback": false }]]
}
}
其他包也会用各自的方式添加模式。expo-location 的 isIosBackgroundLocationEnabled 选项只在你开启时才添加 location。而 expo-background-task 只要安装了,就会在 prebuild 时添加 processing。
保留旧键的 ios/ 文件夹
第二个坑,我在 2026 年 7 月的 Solys 上踩过。我已经从 app.json 里删掉了 audio,但这个键还留在之前生成的 ios/Solys/Info.plist 里。不带 --clean 的 prebuild 会修改这个项目而不是重新生成,插件只会添加键,从不删除。本地构建就会把它打包进去。当 ios/ 被 git 忽略时,云端的 EAS 构建会从全新的 prebuild 开始,我就是这种情况。
每次构建前,我都会检查真正会打包进去的内容:
npx expo config --type introspect --json | grep -o '"UIBackgroundModes":\[[^]]*\]'
npx expo prebuild --clean --platform ios
第一条列出 prebuild 将写入 Info.plist 的模式。第二条会删除 ios/ 文件夹,为本地构建重新生成原生项目。在 Solys 上,第一条输出 "UIBackgroundModes":["audio"],在 TradaZen 上什么都没有:两者都符合预期。
添加或删除模式会修改 Info.plist,也就是修改二进制文件:必须重新构建,远程更新不够。 EAS Update 文档把这类改动归入需要新二进制文件的情况,和 ITMS-90683 一样。
Solys:声明了 audio 模式,而且有真正的理由
Solys 是闹钟,但 audio 模式不是用来响铃的:铃声走的是 AlarmKit,即 Apple 从 iOS 26 起提供的闹钟服务(AlarmKit 文档)。响铃的是系统,即使在静音模式下也会响,而不是应用本身。
这个键的经历如下,因为推理过程比那一行配置更重要:
- 2026 年 7 月底,我把它删了。 当时没有任何东西在后台播放声音:小游戏的音效都在前台,闹钟也不依赖应用。
- 两天后,我又把它加了回来,因为加了夜间监听功能。这个选项用麦克风录下你夜里的声音,并在 iPhone 上本地分析。锁屏时录音必须继续,而 expo-audio 文档说明,后台录音选项同样会添加
audio模式。
理由的性质变了:这个模式是用来录音的,不是用来播放的。 应用里能看到三道保护措施:
- 监听是默认关闭的选项,可以在设置或睡前流程里开启;
- 它有单独的同意界面,这是 2.5.14 条对所有录音的要求,而且数据不会离开手机;
- 麦克风会在闹钟响前十分钟关闭,让监听和铃声永远不会互相干扰。
我没法保证审核员每次都会接受这个声明。但每一项我都能说清楚它的用途,以及在哪里能看到。
让应用保持唤醒的闹钟
在 AlarmKit 之前,第三方闹钟应用没法像 Apple 闹钟那样响铃。于是一些库会让应用一直保持唤醒:Flutter 包 alarm2 的文档描述了一个一直运行到闹钟响起的静音音频播放器。可是静音的声音什么也听不到。从 iOS 26 起,AlarmKit 让这种绕路做法不再必要。
保留还是删除:决策表
| 你的情况 | 怎么做 |
|---|---|
| 前台的简短音效 | 删除 audio |
| 音乐或有声书 | 保留,并演示出来 |
| 长时间录音 | 保留 + 用户同意 |
| 闹钟或计时器 | AlarmKit(iOS 26) |
| 偶尔需要定位 | 重大位置变化服务 |
| 不紧急的同步 | fetch 或 processing |
| 语音或视频通话 | voip 配合 CallKit |
关于定位,Apple 文档把重大位置变化服务列为 location 模式的替代方案。
2.5 的其他条款:2.5.1 和 2.5.2
2.5.1:只用公开 API,框架各司其职
“Apps may only use public APIs and must run on the currently shipping OS.” 应用只能用公开 API,要能在当前系统版本上运行,并放弃已弃用的内容。和 2.5.4 一样,每个框架都要用于它的预定用途,并在描述里说明:HealthKit 用于健康,HomeKit 用于智能家居。如果某个库调用了私有 API,被拒的是你的应用。
2.5.2:不能下载改变应用的代码
应用必须在自己的包内自成一体。它不能“download, install, or execute code which introduces or changes features or functionality of the app”。只有教编程的教育类应用有有限的例外,且代码必须对用户完全可见、可修改。
在 Expo 里,这涉及 EAS Update,它的文档提醒更新必须遵守 App Store 规则。远程更新只用来修 bug,绝不能用来上线审核员没见过的功能。 与审核相关的修复要走新构建,我在 guideline 2.1 的指南里讲过。
怎么回复 2.5.4 被拒?
沟通在你应用的 App Review 部分进行,你在那里回复 App Review 的消息。分两种情况:
- 模式没有用处:删掉它,重新构建,检查 introspect 输出,然后用两句话回复。
- 模式确实服务于某个功能:回复时写清确切路径并附上短视频,之后每个版本的审核备注里都写上这段说明。
我会用的模板如下,请自行调整(如果你的应用没有闹钟,就删掉关于闹钟的那句):
Hello,
The "audio" background mode is used only by [feature], an
optional feature that [records / plays] audio while the
device is locked. It is off by default.
How to test:
1. Open [screen] and turn on [feature].
2. Accept the microphone permission if asked.
3. Tap [button], then lock the device.
[What the reviewer will hear or see.]
Our alarm does not use this mode: it is scheduled with
AlarmKit and rings through the system.
Attached: a short screen recording of these steps.
Best regards,
提交前的 2.5.4 检查清单
- Expo 的 introspect 输出只包含你想要的模式,而且你能说出每个模式对应的功能。
- 凡是默认会添加模式的插件(比如 expo-audio),都没有用简写形式声明。
- 本地
ios/文件夹里没有残留的旧键,或者你从干净的 prebuild 开始编译。 - 功能能快速触发,不需要隐藏设置,审核备注写明了每个模式的用途和测试方法。
- 所有录音都要求明确同意,并显示可见的指示。关于权限请求的规则,见 guideline 5.1.1 的指南。
- 如果是闹钟,铃声走 AlarmKit,而不是由应用播放声音。
提交前检查你的材料
Review Kit 汇集了我的提交前检查清单、给测试员的备注模板,以及会审查你项目的 Claude Code skills。想要真人帮你看,可以和我约一小时:我们视频通话,一起看 Apple 的消息和你的 Info.plist。完整流程见应用被 Apple 拒绝页面。
正在准备第一次上架?做一次免费诊断:它会帮你理清步骤顺序,并发给你我的 Apple 防拒清单。
没人能保证 Apple 会通过你的应用。但一个理由充分的后台模式,三十秒就能讲清楚。
常见问题
“Guideline 2.5.4 - Performance - Software Requirements”是什么意思?
这是 Apple 认为你 Info.plist 里的某个后台模式没有用于预定用途时的被拒标题。消息会点名该模式,并建议你演示使用它的功能,或者删掉这个键。
2.5.4 被拒后需要重新构建吗?
如果你删除或修改了模式,需要:这个键在 Info.plist 里,也就是在二进制文件里。如果模式有正当理由,回复确切路径并附上视频可能就够了。
能为几个界面音效保留 audio 模式吗?
不能。在前台播放的简短音效不需要它。在 Expo 里,把 expo-audio 插件的 enableBackgroundPlayback 设为 false。
闹钟应用需要 audio 模式吗?
如果用的是 iOS 26 起提供的 AlarmKit,响铃就不需要:闹钟由系统播放。在 Solys 上,audio 模式用于夜间监听,在锁屏时录音。
我什么都没声明,Apple 为什么还引用 2.5.4?
可能是某个插件替你声明了:expo-audio 默认添加 audio 模式,而旧的 ios/ 文件夹可能保留了你已从配置中删除的键。用 npx expo config --type introspect 检查一下。

