Guideline 2.5.1 : API publiques et SDK à jour avec Expo
Par Mehdi Azizi
Publié le , 9 min
Guideline 2.5.1 : API publiques seulement, app compatible avec l'iOS actuel, frameworks à leur usage prévu. Avec Expo, contrôle d'abord tes modules natifs.
La guideline 2.5.1 pose quatre exigences : n'utiliser que des API publiques, tourner sur la version d'iOS actuelle, abandonner ce qu'Apple déprécie et employer chaque framework pour son usage prévu. Avec Expo, le risque vient rarement de ton code JavaScript : il vient des modules natifs que tu installes et du SDK avec lequel tu compiles.
Je publie Solys, TradaZen et Nolera avec Expo SDK 57. Solys s'appuie sur l'API Temps d'écran d'Apple, un framework à usage encadré. Ce guide traite la règle de revue. Pour l'erreur reçue à l'envoi du build, lis le guide ITMS-90338. Pour les modes d'arrière-plan, voisins dans la même partie, lis celui de la guideline 2.5.4.
Que dit la guideline 2.5.1 ?
La règle est dans la partie 2.5, « Software Requirements », des App Review Guidelines : « Apps may only use public APIs and must run on the currently shipping OS. Keep your apps up-to-date and make sure you phase out any deprecated features, frameworks or technologies that will no longer be supported in future versions of an OS. Apps should use APIs and frameworks for their intended purposes and indicate that integration in their app description. »
En clair, quatre obligations :
- Des API publiques seulement, c'est-à-dire documentées par Apple.
- Une app qui tourne sur la version d'iOS en cours, iOS 27 depuis septembre 2026.
- Rien de déprécié qui va disparaître : tu remplaces ce qu'Apple annonce en fin de vie.
- Chaque framework à sa place, et cité dans la description : HomeKit pour la maison connectée, HealthKit pour la santé et le sport, relié à l'app Santé.
D'où l'intitulé du refus : « Guideline 2.5.1 - Performance - Software Requirements ».
API publiques : où se cache le risque dans une app Expo
Une API privée est une fonction du système qu'Apple ne documente pas. Apple ne garantit ni son comportement ni sa présence dans la version suivante d'iOS, d'où l'interdiction.
Ton code JavaScript ne touche jamais iOS directement : il passe par des modules natifs. Ceux du SDK Expo sont maintenus par l'équipe d'Expo. Les autres embarquent du code que tu n'as pas écrit, et Apple l'examine comme le tien. Le guide ITMS-90683 montre le même mécanisme avec les phrases d'autorisation : Apple juge le code présent dans le build, pas ce que l'app fait.
Sur Solys, au 15 octobre 2026, 42 dépendances directes contiennent du code iOS natif, dont 14 hors du SDK Expo. On y trouve RevenueCat, Sentry, AppsFlyer et react-native-device-activity, le pont vers l'API Temps d'écran.
Une API privée peut être repérée à deux moments. À l'envoi, l'analyse automatique d'App Store Connect peut renvoyer l'erreur ITMS-90338. Pendant la revue, le reviewer cite la 2.5.1.
API dépréciées : de UIWebView à UIScene
L'exemple le plus connu est UIWebView, l'ancien composant pour afficher du web. Apple a cessé de l'accepter dans les nouvelles apps en avril 2020, puis dans les mises à jour en décembre 2020. Une vieille bibliothèque qui y faisait encore référence bloquait l'envoi. Sur Solys, la recherche de la check-list plus bas ne trouve aucune référence.
Le prochain changement est déjà annoncé. La note technique TN3187 d'Apple l'écrit : « In the next major release following iOS 26, UIScene lifecycle will be required when building with the latest SDK; otherwise, your app won't launch. » En clair, une app compilée avec le SDK d'iOS 27 sans le cycle de vie par scènes ne démarre pas.
Trois dates à relier :
- Depuis avril 2026, Apple exige Xcode 26 : c'est le sujet du guide ITMS-90725.
- En avril 2027, la page d'envoi d'Apple annonce le SDK d'iOS 27 obligatoire.
- Le SDK Expo 58, en bêta depuis le 15 septembre 2026, génère déjà la gestion des scènes, d'après l'annonce d'Expo.
Avec le SDK Expo 57 et Xcode 26, tu compiles encore avec le SDK d'iOS 26 : rien ne casse aujourd'hui. Les modules qui modifient l'AppDelegate devront suivre avant avril 2027.
Frameworks utilisés hors de leur usage prévu
Le reviewer vérifie qu'un framework sensible sert une fonction visible, et que ta fiche la mentionne.
- HealthKit sert la santé et le sport. Les recommandations d'interface d'Apple le disent : « If your app doesn't provide health and fitness functionality, don't request access to people's private health data. »
- HomeKit sert la maison connectée, et rien d'autre.
- PushKit sert les appels en voix sur IP. La documentation de PushKit est nette : « If you are unable to support CallKit in your app, you cannot use PushKit to handle push notifications. » Une notification VoIP qui réveille l'app sans appel est un détournement.
- Family Controls, l'API Temps d'écran, exige une autorisation spéciale. Sa documentation précise : « Before submitting your app to the App Store, you must request permission to use the entitlement. »
Pour Solys, j'ai demandé cette autorisation de distribution le 23 septembre 2026, et Apple l'a accordée le jour même. L'usage colle au framework : l'utilisateur choisit les apps à mettre en pause, et Solys les bloque pendant 30, 45 ou 60 minutes après le réveil. La description de la fiche le dit en une phrase : « Solys utilise l'autorisation Temps d'écran d'Apple pour mettre en pause les apps sélectionnées. » C'est ce que demande la fin de la 2.5.1 : citer l'intégration dans la description.
Versions bêta : TestFlight oui, App Store non
Les notes de version d'App Store Connect montrent la règle en pratique. Le 14 octobre 2026, les builds faits avec Xcode 27.2 bêta 3 sont acceptés « for internal and external testing », donc pour TestFlight. Le 5 octobre, ceux de Xcode 27.1 RC sont acceptés « for the App Store ».
Un build compilé avec une bêta de Xcode part dans TestFlight, jamais en revue. Pour soumettre, il te faut une version finale, ou une RC qu'Apple a ouverte à l'App Store.
Deux précisions pour une app Expo :
- Une bêta d'Expo n'est pas une bêta d'Apple. Apple contrôle la version de Xcode et du SDK iOS, pas celle d'Expo. L'annonce du SDK 58 ajoutait que les images EAS avec Xcode 27 arrivaient bientôt.
- Tester sur l'iOS actuel reste obligatoire, même si tu compiles avec le SDK d'iOS 26. Lance l'app à froid sur un iPhone ou un simulateur à jour.
Check-list : dépendances natives avant soumission
Passe-la avant chaque build de production. Les commandes se lancent à la racine du projet Expo :
npx expo-doctor
npx expo install --check
grep -rlw "UIWebView" node_modules --include='*.m' --include='*.mm' --include='*.swift' --include='*.h'
npx expo-doctorne signale aucun échec. Sur Solys, le 15 octobre 2026 : 20 contrôles sur 21 réussis. L'échec venait de 13 paquets Expo en retard d'un correctif, quenpx expo install --checkaligne.- Chaque module hors du SDK Expo figure dans React Native Directory. Expo Doctor fait ce contrôle par défaut, comme l'indique la documentation d'Expo. Un paquet inconnu mérite une lecture de son code iOS.
- Chaque module natif suit ta version de React Native. Le tableau des versions d'Expo associe le SDK 57 à React Native 0.86. Un module sans publication depuis plusieurs versions est un signal.
- La recherche UIWebView ne renvoie rien. Fais de même pour toute API qu'Apple annonce en fin de vie.
- Chaque framework sensible a sa fonction visible : santé, Temps d'écran, appels, maison. La description la cite, et l'autorisation spéciale est accordée.
- Le build sort d'un Xcode final. Vérifie la version dans les journaux de build EAS.
- L'app démarre à froid sur la version actuelle d'iOS, avec un compte neuf.
- Les modules qui touchent à l'AppDelegate annoncent la prise en charge d'UIScene avant ton passage au SDK d'iOS 27.
Comment répondre à un refus 2.5.1 ?
Le message nomme en général l'API ou le framework en cause. Deux cas :
- Le framework ne sert à rien de visible : retire le module ou la capacité, refais un build, puis réponds en deux phrases.
- Le framework sert une vraie fonction : donne le chemin exact, une capture ou une courte vidéo, et cite l'intégration dans la description de la fiche.
Retirer un module natif modifie le binaire : une mise à jour à distance ne suffit pas. Le guide de la guideline 2.1 explique pourquoi le reviewer ne voit que le code embarqué. La conversation se tient ensuite dans App Store Connect, comme dans le guide pour répondre à App Review.
Vérifier ton projet avant l'envoi
Le Kit Review Apple réunit ma checklist avant l'envoi, mes refus corrigés et des skills Claude Code qui relisent ton projet Expo. Pour un regard humain, réserve une heure avec moi : on lit ensemble le message d'Apple et tes dépendances. La démarche complète est sur la page application refusée par Apple.
Tu prépares ta première sortie ? Fais ton diagnostic gratuit : il t'envoie ma checklist anti-refus Apple.
Questions fréquentes
Que veut dire « Guideline 2.5.1 - Performance - Software Requirements » ?
C'est l'intitulé du refus quand Apple estime que ton app utilise une API non publique, une technologie dépréciée ou un framework hors de son usage prévu. Le message nomme en général l'élément en cause.
Quelle différence entre la guideline 2.5.1 et l'erreur ITMS-90338 ?
ITMS-90338 est une erreur automatique reçue à l'envoi du build, quand l'analyse repère un symbole non public. La 2.5.1 est la règle de revue appliquée par une personne, qui couvre aussi les frameworks détournés et les technologies dépréciées.
Peut-on soumettre une app compilée avec une bêta de Xcode ?
Non. App Store Connect accepte ces builds pour TestFlight seulement. Pour la revue, compile avec une version finale de Xcode, ou une RC qu'Apple a ouverte à l'App Store dans ses notes de version.
Une app Expo peut-elle utiliser une API privée sans le savoir ?
Oui, par un module natif tiers. Ton code JavaScript n'appelle pas iOS lui‑même, mais chaque paquet natif embarque du code Objective-C ou Swift. Lis la liste des modules hors du SDK Expo avant chaque version.
Faut-il passer au SDK Expo 58 tout de suite ?
Pas pour la 2.5.1 au 15 octobre 2026 : le SDK 57 compile avec le SDK d'iOS 26, encore accepté. Prévois la montée avant avril 2027, quand Apple exigera le SDK d'iOS 27 et le cycle de vie par scènes.

