# Guideline 2.5.4: mod de fundal respins de Apple

> Apple respinge un mod de fundal declarat fără o funcție care să-l folosească. Scoate cheia sau arată-i reviewerului funcția.

Pagina originală: [Guideline 2.5.4: mod de fundal respins de Apple](https://devoria.fr/ro/blog/guideline-2-5-4-mod-fundal-respins-apple)
Autor: [Mehdi Azizi](https://devoria.fr/ro/mehdi-azizi)
Publicare: 2026-11-04
Ultima revizuire a conținutului: 2026-11-04


Guideline 2.5.4 limitează modurile de fundal la utilizarea lor prevăzută: sunet, locație, apeluri VoIP, finalizarea sarcinilor, notificări locale. Respingerea vine când Info.plist-ul tău declară unul dintre aceste moduri și reviewerul nu găsește nicio funcție care să aibă nevoie de el. **Scoate cheia dacă nimic nu o folosește, altfel arată-i reviewerului funcția în treizeci de secunde.**

Îmi public propriile aplicații iOS cu Expo. Solys, alarma mea cu mini-jocuri, declară modul audio: l-am scos, apoi l-am pus la loc din alt motiv. Ghidul ăsta se bazează pe textul Apple, pe respingeri publicate de alți dezvoltatori și pe proiectele mele. Pentru imaginea de ansamblu a motivelor, citește [de ce respinge Apple o aplicație](https://devoria.fr/ro/blog/aplicatie-respinsa-apple-cazuri-reale).

## Ce spune guideline 2.5.4?

Regula încape într-o frază, în secțiunea 2 „Performance”, partea 2.5 „Software Requirements”, din [App Review Guidelines](https://developer.apple.com/app-store/review/guidelines/#2.5.4): „Multitasking apps may only use background services for their intended purposes: VoIP, audio playback, location, task completion, local notifications, etc.”

Pe scurt: un serviciu de fundal servește doar scopului pentru care există. De aici titlul „Guideline 2.5.4 - Performance - Software Requirements”.

Implicit, o aplicație trecută în fundal e suspendată. Ca să continue să ruleze, declară unul sau mai multe moduri în cheia `UIBackgroundModes` din Info.plist. [Documentația Apple despre modurile de fundal](https://developer.apple.com/documentation/xcode/configuring-background-execution-modes) cere să le folosești cu măsură, din cauza bateriei, și să preferi altă soluție când există. **Fiecare mod declarat e o promisiune pe care reviewerul o poate verifica.**

## Modurile de fundal și utilizarea lor prevăzută

| Mod                    | Cheie                 | Utilizare prevăzută       |
| ---------------------- | --------------------- | ------------------------- |
| Audio, AirPlay, PiP    | `audio`               | Sunet audibil în fundal   |
| Locație                | `location`            | Locație continuă          |
| Voce prin IP           | `voip`                | Apeluri cu CallKit        |
| Preluare               | `fetch`               | Conținut de rețea regulat |
| Procesare              | `processing`          | Sarcini programate        |
| Notificări la distanță | `remote-notification` | Push de conținut nou      |

Tabelul rezumă pagina Apple. În respingerile publicate pe forumuri, `audio`, `location` și `voip` apar cel mai des.

## Ce înseamnă mesajul de respingere 2.5.4?

Mesajul numește modul în cauză. Două exemple publicate de dezvoltatori pe forumurile Apple:

- **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.” Continuarea precizează că cheia `audio` e făcută pentru aplicațiile care redau un conținut audibil în fundal, ca un player de muzică. Propune două ieșiri: adaugi acel conținut sau scoți cheia ([firul de pe forum](https://developer.apple.com/forums/thread/95216)).
- **Locație**: într-un [fir din decembrie 2024](https://developer.apple.com/forums/thread/771202), Apple n-a găsit nicio funcție în afară de urmărirea angajaților care să ceară locație permanentă și scrie că doar această utilizare nu e potrivită.

Cum o văd eu: **reviewerul nu-ți citește codul, caută o funcție.** Trebuie să o poată porni, să treacă aplicația în fundal și să constate că merge mai departe.

Există și cazul invers. Într-un [fir din mai 2026](https://developer.apple.com/forums/thread/826849), o aplicație de citire cu voce tare, care folosea cu adevărat modul `audio`, a fost respinsă de mai multe ori: reviewerul nu reușea să pornească sunetul. Alt dezvoltator scrie acolo că, după părerea lui, un video atașat i-a deblocat cazul. E o mărturie, nu o regulă Apple.

## De unde vine cheia dacă n-ai adăugat-o tu?

Cu Expo, plugin-urile de configurare completează Info.plist la prebuild. **Un mod de fundal poate deci intra în binarul tău fără să fi decis tu asta.**

### Plugin-ul expo-audio, cu setările implicite

[Documentația expo-audio](https://docs.expo.dev/versions/latest/sdk/audio/) o spune: opțiunea `enableBackgroundPlayback` are implicit valoarea `true` și, pe iOS, adaugă modul `audio`. Să declari plugin-ul în forma scurtă, `"expo-audio"`, e deci suficient ca să declari modul.

Asta am găsit recitind TradaZen înainte de prima trimitere: sunete scurte de interfață în prim-plan, dar un plugin declarat în forma scurtă. Corectura încape în `app.json`:

```json
{
  "expo": {
    "plugins": [["expo-audio", { "enableBackgroundPlayback": false }]]
  }
}
```

Alte pachete adaugă un mod în felul lor. Opțiunea `isIosBackgroundLocationEnabled` din [expo-location](https://docs.expo.dev/versions/latest/sdk/location/) adaugă `location` doar dacă o activezi. [expo-background-task](https://docs.expo.dev/versions/latest/sdk/background-task/), în schimb, adaugă `processing` la prebuild imediat ce e instalat.

### Folderul ios/ care păstrează cheia veche

A doua capcană, trăită pe Solys în iulie 2026. Scosesem `audio` din `app.json`, dar cheia rămânea în `ios/Solys/Info.plist`, generat mai devreme. Un prebuild fără `--clean` modifică proiectul ăsta în loc să-l recreeze, iar plugin-ul adaugă cheia fără s-o scoată vreodată. Un build local ar fi inclus-o. Un build EAS în cloud pornește de la un prebuild nou când `ios/` e ignorat de git, cum era cazul meu.

Înainte de fiecare build, verific ce pleacă de fapt:

```bash
npx expo config --type introspect --json | grep -o '"UIBackgroundModes":\[[^]]*\]'
npx expo prebuild --clean --platform ios
```

Prima listează modurile pe care prebuild-ul le va scrie în Info.plist. A doua recreează proiectul nativ pentru un build local, ștergând folderul `ios/`. Pe Solys, prima afișează `"UIBackgroundModes":["audio"]`, pe TradaZen nimic: ambele sunt intenționate.

Să adaugi sau să scoți un mod modifică Info.plist, deci binarul: **ai nevoie de un build nou, un update la distanță nu ajunge.** [Documentația EAS Update](https://docs.expo.dev/eas-update/introduction/) pune aceste schimbări printre cele care cer un binar nou, ca la [ITMS-90683](https://devoria.fr/ro/blog/itms-90683-missing-purpose-string-expo).

## Solys: un mod audio declarat, cu un motiv real

Solys e o alarmă, dar modul `audio` nu servește la sunatul alarmei: **soneria trece prin AlarmKit**, serviciul de alarmă Apple disponibil din iOS 26 ([documentația AlarmKit](https://developer.apple.com/documentation/alarmkit)). Sistemul sună, chiar și în modul silențios, nu aplicația.

Istoria cheii, pentru că raționamentul contează mai mult decât linia:

1. **La sfârșitul lui iulie 2026, o scot.** Nimic nu reda sunet în fundal: efectele sonore ale mini-jocurilor rămân în prim-plan, iar alarma nu depinde de aplicație.
2. **Două zile mai târziu, o pun la loc**, odată cu ascultarea nopții. Opțiunea asta înregistrează zgomotele din noaptea ta cu microfonul și le analizează pe iPhone. Înregistrarea trebuie să continue cu ecranul blocat, iar documentația expo-audio indică faptul că opțiunea de înregistrare în fundal adaugă și ea modul `audio`.

Justificarea și-a schimbat natura: **modul servește la înregistrat, nu la redat.** Trei măsuri de siguranță, vizibile în aplicație:

- ascultarea e o opțiune dezactivată implicit, care se activează din setări sau din ritualul de seară;
- are propriul ecran de consimțământ, cum cere [regula 2.5.14](https://developer.apple.com/app-store/review/guidelines/#2.5.14) pentru orice înregistrare, și nimic nu părăsește telefonul;
- microfonul se închide cu zece minute înainte de alarmă, ca ascultarea și soneria să nu se încurce niciodată.

Nu pot garanta că un reviewer va accepta mereu declarația asta. Știu să spun, pentru fiecare element, la ce servește și unde se vede.

### Alarmele care țineau aplicația trează

Înainte de AlarmKit, o aplicație de alarmă terță nu putea suna ca alarma Apple. Unele biblioteci țineau deci aplicația trează: documentația pachetului Flutter [alarm2](https://pub.dev/packages/alarm2) descrie un player audio silențios care rulează până la alarmă. Dar un sunet mut nu se aude. **Din iOS 26, AlarmKit face ocolișul ăsta inutil.**

## Păstrezi sau scoți modul: grila de decizie

| Situația ta                | Ce faci                  |
| -------------------------- | ------------------------ |
| Sunete scurte în prim-plan | Scoți `audio`            |
| Muzică sau audiobook       | Păstrezi, îl arăți       |
| Înregistrare lungă         | Păstrezi + consimțământ  |
| Alarmă sau cronometru      | AlarmKit (iOS 26)        |
| Locație din când în când   | Schimbări semnificative  |
| Sincronizare fără urgență  | `fetch` sau `processing` |
| Apeluri audio sau video    | `voip` cu CallKit        |

Pentru locație, pagina Apple citează serviciul de schimbări semnificative ca alternativă la modul `location`.

## Celelalte alineate din 2.5: 2.5.1 și 2.5.2

### 2.5.1: API-uri publice și framework-uri la locul lor

„Apps may only use public APIs and must run on the currently shipping OS.” Aplicația folosește doar API-uri publice, rulează pe versiunea actuală a sistemului și renunță la ce e depreciat. Ca la 2.5.4, fiecare framework servește utilizării lui prevăzute, menționată în descriere: HealthKit pentru sănătate, HomeKit pentru casa inteligentă. Dacă o bibliotecă apelează un API privat, aplicația ta primește respingerea.

### 2.5.2: fără cod descărcat care schimbă aplicația

Aplicația rămâne autonomă în pachetul ei. Nu poate să „download, install, or execute code which introduces or changes features or functionality of the app”. Doar aplicațiile educaționale care învață programare au o excepție limitată, cu un cod complet vizibil și modificabil de utilizator.

Cu Expo, întrebarea atinge EAS Update, a cărui documentație amintește că update-urile trebuie să respecte regulile App Store. **Păstrează update-urile la distanță pentru corecturi, niciodată pentru a livra o funcție pe care reviewerul n-a văzut-o.** O corectură legată de review trece printr-un build nou, cum explic în ghidul despre [guideline 2.1](https://devoria.fr/ro/blog/guideline-2-1-app-store-respingere).

## Cum răspunzi la o respingere 2.5.4?

Conversația are loc în secțiunea App Review a aplicației tale, unde [răspunzi la mesajul App Review](https://developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/reply-to-app-review-messages/). Două cazuri:

- **Modul nu servește la nimic**: scoate-l, refă build-ul, verifică introspecția, apoi răspunde în două fraze.
- **Modul servește o funcție reală**: răspunde cu drumul exact și un video scurt, apoi pune textul ăsta în notele de review ale fiecărei versiuni.

Modelul pe care l-aș folosi, de adaptat (scoate fraza despre alarmă dacă aplicația ta nu are una):

```text
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-ul 2.5.4 înainte de trimitere

- Introspecția Expo afișează doar modurile dorite și știi să numești funcția fiecăruia.
- Niciun plugin nu e declarat în forma scurtă dacă adaugă implicit un mod, ca expo-audio.
- Folderul tău `ios/` local nu păstrează nicio cheie veche, sau compilezi dintr-un prebuild curat.
- Funcția pornește repede, fără setare ascunsă, iar notele de review spun ce mod servește la ce și cum se testează.
- Orice înregistrare cere un consimțământ explicit și afișează un indicator vizibil. Regulile despre cererile de permisiune sunt în ghidul despre [guideline 5.1.1](https://devoria.fr/ro/blog/guideline-5-1-1-refuz-app-store).
- Pentru o alarmă, soneria trece prin AlarmKit, nu printr-un sunet redat din aplicație.

## Verifică-ți dosarul înainte de trimitere

[Review Kit](https://devoria.fr/ro/kits/app-review) adună checklist-ul meu dinainte de trimitere, modele de note pentru tester și skills Claude Code care îți recitesc proiectul. Pentru o privire umană, [rezervă o oră cu mine](https://devoria.fr/ro/coaching): citim împreună mesajul Apple și Info.plist-ul tău, pe video. Demersul complet e pe pagina [aplicație respinsă de Apple](https://devoria.fr/ro/expertise/aplicatie-respinsa-de-apple).

Îți pregătești prima lansare? [Fă-ți diagnosticul gratuit](https://devoria.fr/ro/diagnostic): pune pașii în ordine și îți trimite checklist-ul meu anti-respingere Apple.

Nimeni nu poate garanta că Apple îți va accepta aplicația. Un mod de fundal bine justificat, în schimb, se apără în treizeci de secunde.

## Întrebări frecvente

### Ce înseamnă „Guideline 2.5.4 - Performance - Software Requirements”?

E titlul respingerii când Apple consideră că un mod de fundal din Info.plist-ul tău nu servește utilizării lui prevăzute. Mesajul numește modul și propune să arăți funcția care îl folosește sau să scoți cheia.

### E nevoie de un build nou după o respingere 2.5.4?

Dacă scoți sau modifici un mod, da: cheia e în Info.plist, deci în binar. Dacă modul e justificat, un răspuns cu drumul exact și un video poate fi suficient.

### Pot păstra modul audio pentru câteva sunete de interfață?

Nu. Sunetele scurte redate în prim-plan nu au nevoie de el. Cu Expo, setează `enableBackgroundPlayback` pe `false` în plugin-ul expo-audio.

### O aplicație de alarmă are nevoie de modul audio?

Nu ca să sune, dacă se bazează pe AlarmKit, disponibil din iOS 26: sistemul redă alarma. Pe Solys, modul `audio` servește ascultării nopții, care înregistrează cu ecranul blocat.

### De ce citează Apple 2.5.4 când eu n-am declarat nimic?

Poate un plugin a făcut-o în locul tău: expo-audio adaugă implicit modul `audio`, iar un folder `ios/` vechi poate păstra o cheie scoasă din configurație. Verifică cu `npx expo config --type introspect`.


## Proiectul tău

[Review Kit](https://devoria.fr/ro/kits/app-review): Checklistul meu de review App Store, respingerile mele de la Apple rezolvate, checklistul pentru Google Play și trei skilluri Claude Code. 259 RON.

[iOS & Android Kit](https://devoria.fr/ro/kits/ios): Creează-ți aplicația de iPhone și Android cu Claude Code: codul de pornire al aplicațiilor mele, drumul până în store-uri și toate kiturile. 529 RON.

[Diagnostic: ce te desparte de aplicația ta de iPhone](https://devoria.fr/ro/diagnostic): 7 întrebări, 60 de secunde: afli ce te blochează de fapt să-ți publici aplicația de iPhone, traseul tău în 4 etape și kitul potrivit pentru tine.
