# Guideline 2.5.4 : mode d'arrière-plan refusé par Apple

> Guideline 2.5.4 : Apple refuse un mode d'arrière-plan déclaré sans fonction qui l'utilise. Retire la clé ou montre au reviewer le son, la position ou l'appel.

Page originale : [Guideline 2.5.4 : mode d'arrière-plan refusé par Apple](https://devoria.fr/blog/guideline-2-5-4-modes-arriere-plan)
Auteur : [Mehdi Azizi](https://devoria.fr/mehdi-azizi)
Publication : 2026-11-04
Dernière révision du contenu : 2026-11-04


La guideline 2.5.4 limite les modes d'arrière-plan à leur usage prévu : son, position, appels VoIP, fin de tâche, notifications locales. Le refus tombe quand ton Info.plist déclare un de ces modes et que le reviewer ne trouve aucune fonction qui en a besoin. **Retire la clé si rien ne l'utilise, sinon montre la fonction au reviewer en trente secondes.**

Je publie mes propres apps iOS avec Expo. Solys, mon réveil à mini-jeux, déclare le mode audio : je l'ai retiré, puis remis pour une autre raison. Ce guide s'appuie sur le texte d'Apple, sur des refus publiés par d'autres développeurs et sur mes projets. Pour la vue d'ensemble des motifs, lis [pourquoi Apple refuse une app](https://devoria.fr/blog/pourquoi-apple-refuse-votre-app).

## Que dit la guideline 2.5.4 ?

La règle tient en une phrase, dans la section 2 « Performance », partie 2.5 « Software Requirements », des [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. »

En clair : un service d'arrière-plan ne sert qu'à ce pour quoi il existe. D'où l'intitulé « Guideline 2.5.4 - Performance - Software Requirements ».

Par défaut, une app passée en arrière-plan est suspendue. Pour continuer à tourner, elle déclare un ou plusieurs modes dans la clé `UIBackgroundModes` de son Info.plist. La [documentation d'Apple sur les modes d'arrière-plan](https://developer.apple.com/documentation/xcode/configuring-background-execution-modes) demande de les utiliser avec parcimonie, à cause de la batterie, et de préférer une autre solution quand elle existe. **Chaque mode déclaré est une promesse que le reviewer peut vérifier.**

## Les modes d'arrière-plan et leur usage prévu

| Mode                    | Clé                   | Usage prévu             |
| ----------------------- | --------------------- | ----------------------- |
| Audio, AirPlay, PiP     | `audio`               | Son audible en fond     |
| Position                | `location`            | Position continue       |
| Voix sur IP             | `voip`                | Appels avec CallKit     |
| Récupération            | `fetch`               | Contenu réseau régulier |
| Traitement              | `processing`          | Tâches planifiées       |
| Notifications distantes | `remote-notification` | Push de contenu nouveau |

Ce tableau résume la page d'Apple. Dans les refus publiés sur les forums, `audio`, `location` et `voip` reviennent le plus.

## Que veut dire le message de refus 2.5.4 ?

Le message nomme le mode en cause. Deux exemples publiés par des développeurs sur les forums d'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. » La suite précise que la clé `audio` est faite pour les apps qui font entendre un contenu en arrière-plan, comme un lecteur de musique. Elle propose deux sorties : ajouter ce contenu ou retirer la clé ([fil du forum](https://developer.apple.com/forums/thread/95216)).
- **Position** : dans un [fil de décembre 2024](https://developer.apple.com/forums/thread/771202), Apple n'a trouvé aucune fonction autre que le suivi des employés qui demande une position permanente, et écrit que ce seul usage n'est pas approprié.

Ma lecture : **le reviewer ne lit pas ton code, il cherche une fonction.** Il doit pouvoir la lancer, passer l'app en arrière-plan et constater qu'elle continue.

Le cas inverse existe. Dans un [fil de mai 2026](https://developer.apple.com/forums/thread/826849), une app de lecture à voix haute, qui utilisait vraiment le mode `audio`, a été refusée plusieurs fois : le reviewer ne parvenait pas à déclencher le son. Un autre développeur y écrit qu'à son avis, une vidéo jointe a débloqué son cas. C'est un témoignage, pas une règle d'Apple.

## D'où vient la clé quand tu ne l'as pas ajoutée ?

Avec Expo, ce sont les plugins de configuration qui remplissent l'Info.plist au prebuild. **Un mode d'arrière-plan peut donc entrer dans ton binaire sans que tu l'aies décidé.**

### Le plugin expo-audio, réglé par défaut

La [documentation d'expo-audio](https://docs.expo.dev/versions/latest/sdk/audio/) l'indique : l'option `enableBackgroundPlayback` vaut `true` par défaut et, sur iOS, ajoute le mode `audio`. Déclarer le plugin sous sa forme courte, `"expo-audio"`, suffit donc à déclarer le mode.

C'est ce que j'ai trouvé en relisant TradaZen avant sa première soumission : de courts sons d'interface au premier plan, mais un plugin déclaré en forme courte. Le correctif tient dans `app.json` :

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

D'autres paquets ajoutent un mode à leur façon. L'option `isIosBackgroundLocationEnabled` d'[expo-location](https://docs.expo.dev/versions/latest/sdk/location/) ajoute `location` seulement si tu l'actives. [expo-background-task](https://docs.expo.dev/versions/latest/sdk/background-task/), lui, ajoute `processing` au prebuild dès qu'il est installé.

### Le dossier ios/ qui garde l'ancienne clé

Second piège, vécu sur Solys en juillet 2026. J'avais retiré `audio` de `app.json`, mais la clé restait dans `ios/Solys/Info.plist`, généré plus tôt. Un prebuild sans `--clean` modifie ce projet au lieu de le recréer, et le plugin ajoute la clé sans jamais la retirer. Un build local l'aurait embarquée. Un build EAS dans le cloud repart d'un prebuild neuf quand `ios/` est ignoré par git, ce qui était mon cas.

Avant chaque build, je vérifie ce qui partira vraiment :

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

La première liste les modes que le prebuild écrira dans l'Info.plist. La seconde recrée le projet natif pour un build local, en effaçant le dossier `ios/`. Sur Solys, la première affiche `"UIBackgroundModes":["audio"]`, sur TradaZen rien : les deux sont voulus.

Ajouter ou retirer un mode modifie l'Info.plist, donc le binaire : **il faut un nouveau build, une mise à jour à distance ne suffit pas.** La [documentation d'EAS Update](https://docs.expo.dev/eas-update/introduction/) range ces changements parmi ceux qui demandent un nouveau binaire, comme pour [ITMS-90683](https://devoria.fr/blog/itms-90683-missing-purpose-string-expo).

## Solys : un mode audio déclaré, avec une vraie raison

Solys est un réveil, mais le mode `audio` ne sert pas à faire sonner l'alarme : **la sonnerie passe par AlarmKit**, le service d'alarme d'Apple disponible depuis iOS 26 ([documentation AlarmKit](https://developer.apple.com/documentation/alarmkit)). C'est le système qui sonne, même en mode silencieux, pas l'app.

L'historique de la clé, parce que le raisonnement compte plus que la ligne :

1. **Fin juillet 2026, je la retire.** Rien ne jouait de son en arrière-plan : les bruitages des mini-jeux restent au premier plan, et l'alarme ne dépend pas de l'app.
2. **Deux jours plus tard, je la remets**, avec l'écoute de la nuit. Cette option enregistre les bruits de ta nuit avec le micro et les analyse sur l'iPhone. L'enregistrement doit continuer écran verrouillé, et la documentation d'expo-audio indique que l'option d'enregistrement en arrière-plan ajoute, elle aussi, le mode `audio`.

La justification a changé de nature : **le mode sert à enregistrer, pas à jouer.** Trois garde-fous, visibles dans l'app :

- l'écoute est une option éteinte par défaut, qui s'active depuis les réglages ou le rituel du soir ;
- elle a son propre écran de consentement, comme l'exige la [règle 2.5.14](https://developer.apple.com/app-store/review/guidelines/#2.5.14) pour tout enregistrement, et rien ne quitte le téléphone ;
- le micro se ferme dix minutes avant l'alarme, pour que l'écoute et la sonnerie ne se gênent jamais.

Je ne peux pas garantir qu'un reviewer acceptera toujours cette déclaration. Je sais dire, pour chaque élément, à quoi il sert et où le voir.

### Les réveils qui gardaient l'app éveillée

Avant AlarmKit, une app de réveil tierce ne pouvait pas sonner comme l'alarme d'Apple. Certaines bibliothèques gardaient donc l'app éveillée : la documentation du paquet Flutter [alarm2](https://pub.dev/packages/alarm2) décrit un lecteur audio silencieux qui tourne jusqu'à l'alarme. Or un son muet ne fait rien entendre. **Depuis iOS 26, AlarmKit rend ce détour inutile.**

## Garder ou retirer le mode : la grille de décision

| Ta situation                | Que faire                 |
| --------------------------- | ------------------------- |
| Sons courts au premier plan | Retirer `audio`           |
| Musique ou livre audio      | Garder, le montrer        |
| Enregistrement long         | Garder + consentement     |
| Réveil ou minuteur          | AlarmKit (iOS 26)         |
| Position de temps en temps  | Changements significatifs |
| Synchro sans urgence        | `fetch` ou `processing`   |
| Appels audio ou vidéo       | `voip` avec CallKit       |

Pour la position, la page d'Apple cite le service de changements significatifs comme alternative au mode `location`.

## Les autres alinéas de la 2.5 : 2.5.1 et 2.5.2

### 2.5.1 : API publiques et frameworks à leur place

« Apps may only use public APIs and must run on the currently shipping OS. » L'app n'utilise que les API publiques, tourne sur la version actuelle du système et abandonne ce qui est déprécié. Comme pour la 2.5.4, chaque framework sert à son usage prévu, mentionné dans la description : HealthKit pour la santé, HomeKit pour la maison connectée. Si une bibliothèque appelle une API privée, c'est ton app qui porte le refus.

### 2.5.2 : pas de code téléchargé qui change l'app

L'app reste autonome dans son paquet. Elle ne peut pas « download, install, or execute code which introduces or changes features or functionality of the app ». Seules les apps éducatives qui apprennent à coder ont une exception limitée, avec un code entièrement visible et modifiable par l'utilisateur.

Avec Expo, la question touche EAS Update, dont la documentation rappelle que les mises à jour doivent respecter les règles de l'App Store. **Garde les mises à jour à distance pour corriger, jamais pour livrer une fonction que le reviewer n'a pas vue.** Un correctif lié à la revue passe par un nouveau build, comme je l'explique dans le guide de la [guideline 2.1](https://devoria.fr/blog/guideline-2-1-app-store-refus).

## Comment répondre à un refus 2.5.4 ?

La conversation se tient dans la section App Review de ton app, où tu [réponds au message d'App Review](https://developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/reply-to-app-review-messages/). Deux cas :

- **Le mode ne sert à rien** : retire-le, refais un build, vérifie l'introspection, puis réponds en deux phrases.
- **Le mode sert une vraie fonction** : réponds avec le chemin exact et une courte vidéo, puis reprends ce texte dans les notes de revue de chaque version.

Le modèle que j'utiliserais, à adapter (retire la phrase sur l'alarme si ton app n'en a pas) :

```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,
```

## La checklist 2.5.4 avant soumission

- L'introspection Expo n'affiche que les modes voulus, et tu sais nommer la fonction de chacun.
- Aucun plugin n'est déclaré en forme courte s'il ajoute un mode par défaut, comme expo-audio.
- Ton dossier `ios/` local ne garde aucune ancienne clé, ou tu compiles depuis un prebuild propre.
- La fonction se déclenche vite, sans réglage caché, et les notes de revue disent quel mode sert à quoi et comment le tester.
- Tout enregistrement demande un consentement explicite et affiche un indicateur visible. Les règles sur les demandes d'autorisation sont dans le guide de la [guideline 5.1.1](https://devoria.fr/blog/guideline-5-1-1-app-store-refus).
- Pour un réveil, la sonnerie passe par AlarmKit, pas par un son joué depuis l'app.

## Vérifier ton dossier avant l'envoi

Le [Kit Review Apple](https://devoria.fr/kits/review-apple) réunit ma checklist avant l'envoi, des modèles de notes pour le testeur et des skills Claude Code qui relisent ton projet. Pour un regard humain, [réserve une heure avec moi](https://devoria.fr/coaching) : on lit le message d'Apple et ton Info.plist ensemble, en visio. La démarche complète est sur la page [application refusée par Apple](https://devoria.fr/expertise/application-refusee-par-apple).

Tu prépares ta première sortie ? [Fais ton diagnostic gratuit](https://devoria.fr/diagnostic) : il remet les étapes dans l'ordre et t'envoie ma checklist anti-refus Apple.

Personne ne peut garantir qu'Apple acceptera ton app. Un mode d'arrière-plan bien justifié, lui, se défend en trente secondes.

## Questions fréquentes

### Que veut dire « Guideline 2.5.4 - Performance - Software Requirements » ?

C'est l'intitulé du refus quand Apple estime qu'un mode d'arrière-plan de ton Info.plist ne sert pas à son usage prévu. Le message nomme le mode et propose de montrer la fonction qui l'utilise ou de retirer la clé.

### Faut-il un nouveau build après un refus 2.5.4 ?

Si tu retires ou modifies un mode, oui : la clé est dans l'Info.plist, donc dans le binaire. Si le mode est justifié, une réponse avec le chemin exact et une vidéo peut suffire.

### Peut-on garder le mode audio pour quelques sons d'interface ?

Non. Des sons courts joués au premier plan n'en ont pas besoin. Avec Expo, règle `enableBackgroundPlayback` sur `false` dans le plugin expo-audio.

### Une app de réveil a-t-elle besoin du mode audio ?

Pas pour sonner, si elle s'appuie sur AlarmKit, disponible depuis iOS 26 : c'est le système qui joue l'alarme. Sur Solys, le mode `audio` sert à l'écoute de la nuit, qui enregistre écran verrouillé.

### Pourquoi Apple cite la 2.5.4 alors que je n'ai rien déclaré ?

Un plugin l'a peut-être fait pour toi : expo-audio ajoute le mode `audio` par défaut, et un ancien dossier `ios/` peut garder une clé retirée de ta configuration. Vérifie avec `npx expo config --type introspect`.


## Ton projet

[Kit Review](https://devoria.fr/kits/review-apple) : Tout ce que je vérifie avant d'envoyer une app à Apple, la même vérification pour Google Play, et trois skills qui font la relecture avec Claude Code. 49 €, paiement unique. Inclus : La checklist avant l'envoi ; Les refus que j'ai pris, et ce que j'ai corrigé ; Les notes pour le testeur ; Les skills de vérification. Prérequis : une app iPhone ou Android presque prête, et Claude Code ou Cursor. Téléchargement immédiat après le paiement.

[Kit iOS & Android Devoria](https://devoria.fr/kits/ios) : Le code de départ de mes apps, le parcours jusqu'à l'App Store et Google Play avec les messages à donner à Claude, et tous les kits. Claude part d'une app qui tourne déjà. 99 €, paiement unique. Inclus : Le code de départ de ton app ; Les styles visuels ; Le parcours pas à pas ; Kit Review ; Kit Captures ; Kit ASO ; Mises à jour à vie ; Bonus : la séance 1:1 à moitié prix. Prérequis : pour l'iPhone, un Mac avec Xcode 26 ou plus et un compte Apple Developer (99 $ par an) pour publier. Pour Android, Android Studio sur un Mac, un PC Windows ou Linux, et un compte Google Play Console (25 $, une fois). Et Claude Code (abonnement payant) ou Cursor. Téléchargement immédiat après le paiement.

[Diagnostic gratuit](https://devoria.fr/diagnostic) : quelques questions sur ton projet. Il dit ce qui te bloque vraiment, l'ordre des quatre étapes et le kit qui correspond. En laissant ton e-mail, tu reçois la checklist anti-refus Apple : les points vérifiés avant chaque envoi, tirés des refus reçus par les apps du studio.

[Une heure avec moi](https://devoria.fr/coaching) : On regarde ton app ou ton projet Claude, écran partagé : ce qui bloque, ce que je change en premier, et dans quel ordre. 100 € la séance d'une heure, en visio, paiement en une fois. Sujets : L'audit de ton app ; Ton travail avec Claude ; Ta fiche et ton paywall ; Un refus d'Apple.
