Guideline 2.5.4: Apple zamítl režim na pozadí
Autor: Mehdi Azizi
Publikováno , 9 min
Guideline 2.5.4: Apple zamítne režim na pozadí, který žádná funkce nepoužívá. Odeber klíč, nebo reviewerovi ukaž zvuk, polohu či hovor.
Guideline 2.5.4 omezuje režimy na pozadí na jejich zamýšlené použití: zvuk, poloha, VoIP hovory, dokončení úlohy, lokální notifikace. K zamítnutí dojde, když tvůj Info.plist deklaruje některý z těchto režimů a reviewer nenajde žádnou funkci, která by ho potřebovala. Pokud ho nic nepoužívá, klíč odeber, jinak reviewerovi ukaž funkci do třiceti sekund.
Své vlastní iOS aplikace vydávám s Expo. Solys, můj budík s minihrami, deklaruje režim audio: odebral jsem ho a pak ho z jiného důvodu vrátil. Tenhle návod vychází z textu Applu, ze zamítnutí, která zveřejnili jiní vývojáři, a z mých projektů. Celkový přehled důvodů najdeš v článku proč Apple zamítá aplikace.
Co říká guideline 2.5.4?
Pravidlo má jednu větu, v sekci 2 „Performance“, části 2.5 „Software Requirements“ v App Review Guidelines: „Multitasking apps may only use background services for their intended purposes: VoIP, audio playback, location, task completion, local notifications, etc.“
Jednoduše: služba na pozadí slouží jen k tomu, k čemu existuje. Odtud název „Guideline 2.5.4 - Performance - Software Requirements“.
Ve výchozím stavu se aplikace po přechodu na pozadí uspí. Aby běžela dál, deklaruje jeden nebo více režimů v klíči UIBackgroundModes ve svém Info.plist. Dokumentace Applu k režimům na pozadí žádá, abys je kvůli baterii používal střídmě a dal přednost jinému řešení, pokud existuje. Každý deklarovaný režim je slib, který si reviewer může ověřit.
Režimy na pozadí a jejich zamýšlené použití
| Režim | Klíč | Zamýšlené použití |
|---|---|---|
| Audio, AirPlay, PiP | audio | Slyšitelný zvuk v pozadí |
| Poloha | location | Nepřetržitá poloha |
| Voice over IP | voip | Hovory přes CallKit |
| Načítání | fetch | Pravidelný obsah ze sítě |
| Zpracování | processing | Plánované úlohy |
| Vzdálené notifikace | remote-notification | Push nového obsahu |
Tabulka shrnuje stránku Applu. V zamítnutích zveřejněných na fórech se nejčastěji objevují audio, location a voip.
Co znamená zpráva o zamítnutí 2.5.4?
Zpráva jmenuje režim, o který jde. Dva příklady, které vývojáři zveřejnili na fórech Applu:
- Audio: „Your app still declares support for audio in the UIBackgroundModes key in your Info.plist but did not include features that require persistent audio.“ Dál se upřesňuje, že klíč
audioje určený pro aplikace, které na pozadí přehrávají slyšitelný obsah, jako hudební přehrávač. Nabízí dvě cesty: takový obsah přidat, nebo klíč odebrat (vlákno na fóru). - Poloha: ve vláknu z prosince 2024 Apple nenašel kromě sledování zaměstnanců žádnou funkci, která by vyžadovala trvalou polohu, a napsal, že samotné tohle použití není vhodné.
Jak to čtu já: reviewer nečte tvůj kód, hledá funkci. Musí ji umět spustit, přepnout aplikaci na pozadí a zjistit, že běží dál.
Existuje i opačný případ. Ve vláknu z května 2026 byla aplikace pro předčítání nahlas, která režim audio opravdu používala, několikrát zamítnuta: reviewer nedokázal zvuk spustit. Jiný vývojář tam píše, že podle něj jeho případ odblokovalo přiložené video. Je to svědectví, ne pravidlo Applu.
Odkud se klíč vzal, když jsi ho nepřidal?
S Expo plní Info.plist při prebuildu konfigurační pluginy. Režim na pozadí se tak může dostat do tvého binárky, aniž by ses tak rozhodl.
Plugin expo-audio ve výchozím nastavení
Dokumentace expo-audio to uvádí: volba enableBackgroundPlayback má výchozí hodnotu true a na iOS přidává režim audio. Stačí tedy deklarovat plugin v krátké podobě, "expo-audio", a režim je deklarovaný.
Přesně tohle jsem našel při kontrole TradaZen před prvním odesláním: krátké zvuky rozhraní v popředí, ale plugin deklarovaný v krátké podobě. Oprava se vejde do app.json:
{
"expo": {
"plugins": [["expo-audio", { "enableBackgroundPlayback": false }]]
}
}
Jiné balíčky přidávají režim po svém. Volba isIosBackgroundLocationEnabled v expo-location přidá location, jen pokud ji zapneš. expo-background-task naopak přidá processing při prebuildu hned, jak ho nainstaluješ.
Složka ios/, která drží starý klíč
Druhá past, zažil jsem ji na Solys v červenci 2026. Odebral jsem audio z app.json, ale klíč zůstal v ios/Solys/Info.plist, vygenerovaném dřív. Prebuild bez --clean tenhle projekt upravuje, místo aby ho vytvořil znovu, a plugin klíč přidává, ale nikdy neodebírá. Lokální build by ho přibalil. Build přes EAS v cloudu začíná z čistého prebuildu, když je ios/ ignorovaná gitem, což byl můj případ.
Před každým buildem si ověřím, co se opravdu odešle:
npx expo config --type introspect --json | grep -o '"UIBackgroundModes":\[[^]]*\]'
npx expo prebuild --clean --platform ios
První příkaz vypíše režimy, které prebuild zapíše do Info.plist. Druhý znovu vytvoří nativní projekt pro lokální build a smaže přitom složku ios/. U Solys první vypíše "UIBackgroundModes":["audio"], u TradaZen nic: obojí je záměr.
Přidání nebo odebrání režimu mění Info.plist, tedy binárku: potřebuješ nový build, vzdálená aktualizace nestačí. Dokumentace EAS Update řadí tyhle změny mezi ty, které vyžadují novou binárku, stejně jako u ITMS-90683.
Solys: deklarovaný režim audio se skutečným důvodem
Solys je budík, ale režim audio neslouží k vyzvánění budíku: vyzvánění jde přes AlarmKit, službu budíků od Applu dostupnou od iOS 26 (dokumentace AlarmKit). Zvoní systém, i v tichém režimu, ne aplikace.
Historie klíče, protože úvaha je důležitější než samotný řádek:
- Koncem července 2026 ho odeberu. Nic nepřehrávalo zvuk na pozadí: zvukové efekty miniher zůstávají v popředí a budík na aplikaci nezávisí.
- O dva dny později ho vrátím, kvůli nočnímu poslechu. Tahle volba nahrává zvuky tvé noci mikrofonem a analyzuje je přímo v iPhonu. Nahrávání musí pokračovat i při zamčené obrazovce a dokumentace expo-audio uvádí, že volba nahrávání na pozadí také přidává režim
audio.
Zdůvodnění změnilo povahu: režim slouží k nahrávání, ne k přehrávání. Tři pojistky, viditelné v aplikaci:
- poslech je volba ve výchozím stavu vypnutá, zapíná se v nastavení nebo ve večerním rituálu;
- má vlastní obrazovku se souhlasem, jak to pravidlo 2.5.14 vyžaduje u každého nahrávání, a nic neopouští telefon;
- mikrofon se zavře deset minut před budíkem, aby si poslech a vyzvánění nikdy nepřekážely.
Nemůžu zaručit, že reviewer tuhle deklaraci vždycky přijme. U každého prvku ale umím říct, k čemu slouží a kde ho vidět.
Budíky, které držely aplikaci vzhůru
Před AlarmKit nemohla aplikace budíku třetí strany zvonit jako budík od Applu. Některé knihovny proto držely aplikaci vzhůru: dokumentace Flutter balíčku alarm2 popisuje tichý audio přehrávač, který běží až do budíku. Jenže ztlumený zvuk nic nepřehrává slyšitelně. Od iOS 26 je tahle oklika díky AlarmKit zbytečná.
Ponechat, nebo odebrat režim: rozhodovací tabulka
| Tvoje situace | Co udělat |
|---|---|
| Krátké zvuky v popředí | Odebrat audio |
| Hudba nebo audiokniha | Ponechat, ukázat |
| Dlouhé nahrávání | Ponechat + souhlas |
| Budík nebo časovač | AlarmKit (iOS 26) |
| Občasná poloha | Významné změny polohy |
| Synchronizace bez spěchu | fetch nebo processing |
| Audio nebo video hovory | voip s CallKit |
U polohy uvádí stránka Applu jako alternativu k režimu location službu významných změn polohy.
Další body části 2.5: 2.5.1 a 2.5.2
2.5.1: veřejná API a frameworky na svém místě
„Apps may only use public APIs and must run on the currently shipping OS.“ Aplikace používá jen veřejná API, běží na aktuální verzi systému a opouští, co je zastaralé. Stejně jako u 2.5.4 slouží každý framework ke svému zamýšlenému použití, uvedenému v popisu: HealthKit pro zdraví, HomeKit pro chytrou domácnost. Pokud knihovna volá privátní API, zamítnutí nese tvoje aplikace.
2.5.2: žádný stažený kód, který mění aplikaci
Aplikace zůstává soběstačná ve svém balíčku. Nesmí „download, install, or execute code which introduces or changes features or functionality of the app“. Omezenou výjimku mají jen vzdělávací aplikace, které učí programovat, s kódem plně viditelným a upravitelným uživatelem.
S Expo se to týká EAS Update, jehož dokumentace připomíná, že aktualizace musí dodržovat pravidla App Store. Vzdálené aktualizace používej na opravy, nikdy na dodání funkce, kterou reviewer neviděl. Oprava související s revizí jde přes nový build, jak vysvětluju v návodu ke guideline 2.1.
Jak odpovědět na zamítnutí 2.5.4?
Konverzace probíhá v sekci App Review tvé aplikace, kde odpovídáš na zprávu od App Review. Dva případy:
- Režim k ničemu neslouží: odeber ho, udělej nový build, zkontroluj introspekci a odpověz dvěma větami.
- Režim slouží skutečné funkci: odpověz přesným postupem a krátkým videem, pak tenhle text zopakuj v poznámkách pro revizi u každé verze.
Šablona, kterou bych použil, uprav si ji (větu o budíku smaž, pokud tvoje aplikace budík nemá):
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,
Checklist 2.5.4 před odesláním
- Introspekce Expo ukazuje jen zamýšlené režimy a u každého umíš pojmenovat jeho funkci.
- Žádný plugin, který ve výchozím stavu přidává režim (jako expo-audio), není deklarovaný v krátké podobě.
- Tvoje lokální složka
ios/nedrží žádný starý klíč, nebo kompiluješ z čistého prebuildu. - Funkce se spustí rychle, bez skrytého nastavení, a poznámky pro revizi říkají, který režim k čemu slouží a jak ho otestovat.
- Každé nahrávání žádá výslovný souhlas a zobrazuje viditelný indikátor. Pravidla pro žádosti o oprávnění najdeš v návodu ke guideline 5.1.1.
- U budíku jde vyzvánění přes AlarmKit, ne přes zvuk přehrávaný z aplikace.
Zkontroluj si podklady před odesláním
Review Kit obsahuje můj checklist před odesláním, šablony poznámek pro testera a skills pro Claude Code, které projdou tvůj projekt. Pokud chceš lidský pohled, zarezervuj si se mnou hodinu: projdeme spolu zprávu od Applu a tvůj Info.plist přes videohovor. Celý postup najdeš na stránce aplikace zamítnutá Applem.
Chystáš své první vydání? Udělej si bezplatnou diagnostiku: seřadí ti kroky a pošle ti můj checklist proti zamítnutí Applem.
Nikdo nemůže zaručit, že Apple tvou aplikaci přijme. Dobře zdůvodněný režim na pozadí ale obhájíš za třicet sekund.
Časté dotazy
Co znamená „Guideline 2.5.4 - Performance - Software Requirements“?
Je to název zamítnutí, když Apple usoudí, že režim na pozadí v tvém Info.plist neslouží svému zamýšlenému použití. Zpráva jmenuje režim a navrhuje ukázat funkci, která ho používá, nebo klíč odebrat.
Je po zamítnutí 2.5.4 potřeba nový build?
Pokud režim odebíráš nebo měníš, ano: klíč je v Info.plist, tedy v binárce. Pokud je režim oprávněný, může stačit odpověď s přesným postupem a videem.
Můžu si nechat režim audio kvůli pár zvukům rozhraní?
Ne. Krátké zvuky přehrávané v popředí ho nepotřebují. S Expo nastav v pluginu expo-audio enableBackgroundPlayback na false.
Potřebuje aplikace budíku režim audio?
Ke zvonění ne, pokud stojí na AlarmKit, dostupném od iOS 26: budík přehrává systém. V Solys slouží režim audio nočnímu poslechu, který nahrává při zamčené obrazovce.
Proč Apple zmiňuje 2.5.4, když jsem nic nedeklaroval?
Možná to za tebe udělal plugin: expo-audio přidává režim audio ve výchozím stavu a stará složka ios/ může držet klíč, který jsi z konfigurace odebral. Ověř to pomocí npx expo config --type introspect.

