Aller au contenu
useffect.sh
Planifier 30 min avec un senior
Guide · iOS

SDK iOS 27 obligatoire en avril 2027 : ce que ça change pour React Native et Expo

À partir d’avril 2027, toute app envoyée sur App Store Connect doit être compilée avec le SDK iOS 27. Pour une app React Native, ce n’est pas une simple mise à jour de Xcode : compilée avec ce SDK, une app qui n’a pas adopté le cycle de vie UIScene ne se lance pas.

Par Jérémy Magrin ·

Réponse courte

Apple l’a annoncé le 9 septembre 2026 : à partir d’avril 2027, les apps iOS et iPadOS envoyées sur App Store Connect doivent être compilées avec le SDK iOS 27 ou ultérieur, donc avec Xcode 27, qui exige macOS Tahoe 26.6. Le jour exact n’est pas encore publié. Pour React Native et Expo, ce changement de SDK a deux effets. D’abord, une app compilée avec le SDK iOS 27 doit adopter le cycle de vie UIScene, sinon elle ne se lance pas. React Native 0.88 est la première version à le prendre en charge ; aucun patch 0.87 ou 0.86 ne l’a reçu. Expo SDK 58 génère la configuration par défaut, et SDK 57 la propose en opt-in depuis expo 57.0.23. Ensuite, la clé UIDesignRequiresCompatibility, qui désactivait Liquid Glass, est ignorée. Une équipe doit donc planifier la montée vers React Native 0.88 ou Expo SDK 58, migrer son AppDelegate et revoir son interface avant le printemps.

Chaque printemps, Apple relève la version minimale de Xcode exigée pour publier. D’habitude, c’est un changement d’image de CI et quelques avertissements de compilation. Cette année, le SDK iOS 27 impose un changement d’architecture au démarrage de l’app, et React Native ne le prend en charge que depuis la 0.88. Ce guide reprend les sources primaires et détaille ce qu’une équipe React Native ou Expo doit faire avant avril 2027.

Le calendrier

Le 9 septembre 2026, en ouvrant les soumissions pour iOS 27, Apple a publié la règle suivante (nouvelle fenêtre) : « Starting April 2027, apps and games uploaded to App Store Connect need to meet the following minimum requirements », dont « iOS and iPadOS apps must be built with the iOS 27 & iPadOS 27 SDK or later ».

DateÉvénementSource
28 avril 2026Exigence en vigueur : Xcode 26 et SDK iOS 26Upcoming requirements (nouvelle fenêtre)
30 juin 2026Expo SDK 57 (React Native 0.86)changelog Expo (nouvelle fenêtre)
9 septembre 2026Soumissions iOS 27 ouvertes ; annonce de l’exigence d’avril 2027Apple Developer News (nouvelle fenêtre)
15 septembre 2026expo 57.0.23 : support opt-in du cycle de vie UIScene sur SDK 57expo.fyi (nouvelle fenêtre), npm
15 octobre 2026React Native 0.88 publié sur npm (support SceneDelegate, billet du 19 octobre) et Expo SDK 58blog 0.88 (nouvelle fenêtre), changelog Expo (nouvelle fenêtre)
21 octobre 2026Guide de mise à jour Expo : les alias EAS sdk-58 et latest passent sur Xcode 27.1blog Expo (nouvelle fenêtre)
1er novembre 2026Google Play : fin des extensions pour le ciblage de l’API 36Play Console Help (nouvelle fenêtre)
Avril 2027 (jour non publié)Uploads App Store Connect : SDK iOS 27 ou ultérieur obligatoireApple Developer News (nouvelle fenêtre)

Trois précisions.

Le jour n’est pas connu. Sur les forums développeurs (nouvelle fenêtre), un ingénieur Apple répond qu’Apple ne peut pas « disclose, confirm, or comment on exact dates for future SDK requirements » avant leur annonce officielle. Au 27 octobre 2026, la page Upcoming requirements (nouvelle fenêtre) ne mentionne pas encore l’exigence d’avril 2027.

Le SDK impose Xcode 27. Apple parle de SDK, pas de Xcode, mais le SDK iOS 27 n’est livré qu’avec Xcode 27. D’après la page des prérequis (nouvelle fenêtre), Xcode 27, 27.1 et 27.2 RC exigent « macOS Tahoe 26.6 or later ». Les Mac de build et les runners de CI sont donc concernés eux aussi.

La page de soumission (nouvelle fenêtre) ajoute pour avril 2027 « and target iOS 15 or later », alors que la page des exigences indique « must target iOS 13 or later » depuis le 9 septembre 2026. Les deux seuils ne s’appliquent pas aux mêmes dates, et la différence n’a pas d’effet pratique : Expo SDK 56 à 58 exigent déjà iOS 16.4 au minimum, d’après le tableau des versions (nouvelle fenêtre).

Ce que le SDK iOS 27 change pour une app React Native

Le cycle de vie UIScene devient obligatoire

C’est le point bloquant. La documentation UIKit (nouvelle fenêtre) est sans ambiguïté : « Adopting the scene-based life cycle is required. Beginning in iOS 27, iPadOS 27, Mac Catalyst 27, tvOS 27, and visionOS 27, apps built with the latest SDK must adopt the scene-based life cycle or they fail to launch. »

Apple considère qu’une app doit migrer si l’une de ces deux conditions est vraie : la clé UIApplicationSceneManifest est absente de l’Info.plist ou ne déclare aucune configuration, ou l’app delegate n’implémente pas application(_:configurationForConnecting:options:). Jusqu’à React Native 0.87, le template remplit les deux conditions : l’AppDelegate crée la fenêtre dans didFinishLaunchingWithOptions et l’Info.plist ne déclare aucune scène.

L’obligation est liée au SDK, pas à la version d’iOS de l’utilisateur. Un ingénieur Apple l’écrit sur les forums (nouvelle fenêtre) : « The requirement is enforced when building with the new 27.0 SDKs (all of them). If you continue to build with the older SDKs, the requirement is not enforced. » C’est pour cela qu’avril 2027 est la vraie échéance : tant que vous compilez avec Xcode 26, rien ne casse ; le jour où App Store Connect refuse Xcode 26, la migration devient obligatoire. Dans un autre fil (nouvelle fenêtre), un ingénieur Apple conseille à un développeur dont les apps reposent encore sur l’AppDelegate de « prioritize migrating your legacy codebases to the scene-based lifecycle ».

La migration ne se limite pas à ajouter un fichier. Sous le cycle de vie par scènes, UIKit n’appelle plus certaines méthodes de UIApplicationDelegate. Le guide de migration Expo (nouvelle fenêtre) en donne la liste :

  • application(_:open:options:), qui reçoit les deep links ;
  • application(_:continue:restorationHandler:), qui reçoit les universal links et Handoff ;
  • applicationDidBecomeActive(_:), applicationWillResignActive(_:), applicationDidEnterBackground(_:) et applicationWillEnterForeground(_:) ;
  • application(_:performActionFor:completionHandler:), pour les quick actions.

Sans retransmission, tout code natif branché sur ces méthodes, dans votre AppDelegate ou dans une librairie qui l’intercepte, cesse de recevoir les événements (Expo assure cette retransmission, voir plus bas). Les symptômes sont discrets : un lien profond qui ouvre l’app sans naviguer, une quick action sans effet, un SDK d’analytics qui ne voit plus les retours au premier plan.

Liquid Glass ne peut plus être désactivé

Beaucoup d’apps ont ajouté UIDesignRequiresCompatibility à leur Info.plist en 2026 pour garder l’apparence d’avant Liquid Glass. La documentation de la clé (nouvelle fenêtre) la présente comme temporaire et précise : « The system ignores this key when you build for iOS 27 or later ». Les composants natifs de votre app, barres de navigation, onglets, alertes, prendront donc l’apparence Liquid Glass au premier build avec Xcode 27.

Les apps iPhone deviennent redimensionnables

Le changelog d’Expo SDK 58 (nouvelle fenêtre) indique qu’iOS 27 « makes iPhone apps resizable », que requireFullScreen ne permet plus de s’y soustraire et que ScreenOrientation.lockAsync « may have no effect while the app is resizable ». Le billet React Native 0.88 (nouvelle fenêtre) confirme que, sous UIScene, la fenêtre est redimensionnable et que Dimensions.get() et useWindowDimensions() suivent sa taille. Une app qui suppose un écran fixe ou un portrait verrouillé doit être retestée.

L’outillage bouge aussi

Xcode 27 remplace Simulator.app par Device Hub ; Expo CLI le prend en charge depuis SDK 58. Côté CocoaPods, l’issue #12927 (nouvelle fenêtre), ouverte le 24 septembre 2026 et toujours sans réponse au 27 octobre, signale qu’un projet créé avec le template de Xcode 27.0 a objectVersion = 110 et fait échouer pod install. Nous n’avons pas vérifié si Xcode 27 réécrit cette valeur dans un projet existant. Notre guide sur le passage de CocoaPods en lecture seule détaille ce point.

Où en est React Native

React Native 0.88, publié sur npm le 15 octobre 2026 et annoncé le 19, est la première version qui prend en charge le cycle de vie UIScene. Le billet est explicite : « Starting with the iOS 27 SDK, Apple requires the UIScene lifecycle: UIKit apps built with Xcode 27 will fail to launch. » Le support est additif : le chemin AppDelegate reste compatible, et RCTReactNativeFactory gagne deux points d’entrée, startReactNativeWithModuleName:inWindow:connectionOptions: et sa variante avec initialProperties.

VersionStatutXcode minimumCycle de vie UIScene
0.88Dernière version stable26.0Pris en charge
0.87Supportée26.0Non (0.87.1, 26 août 2026)
0.86Supportée16.1Non (0.86.3, 24 août 2026)
0.85 et antérieuresNon supportées depuis la 0.88 (déduit de la règle des 3 dernières mineures)Selon la versionNon

La colonne Xcode vient du tableau de support (nouvelle fenêtre) du groupe de travail des releases ; la colonne UIScene, du CHANGELOG (nouvelle fenêtre), où l’entrée « Add SceneDelegate lifecycle support » n’apparaît que sous v0.88.0. Le billet 0.88 ne dit pas si un backport est prévu. Un Xcode minimum à 26.0 signifie que la version compile avec Xcode 26 ; cela ne garantit pas qu’une app sans scène se lance avec Xcode 27.

Pour migrer une app React Native nue, le billet liste trois étapes :

  • déplacer le point d’entrée React Native de l’AppDelegate vers un SceneDelegate ;
  • transmettre les callbacks d’URL et d’activité utilisateur de la scène à RCTLinkingManager ;
  • ajouter la clé UIApplicationSceneManifest à l’Info.plist.

Le template communautaire est déjà à jour : les fichiers SceneDelegate.swift (nouvelle fenêtre) et Info.plist (nouvelle fenêtre) de la branche 0.88 servent de référence, et l’upgrade helper (nouvelle fenêtre) montre le diff complet.

Deux limites à connaître. Le support de la 0.88 est « limited to a single scene », donc UIApplicationSupportsMultipleScenes doit rester à false. Et au lancement, React Native ne transmet que le premier contexte d’URL ou la première activité utilisateur reçus par la scène.

La 0.88 n’a, selon son billet, « no user-facing breaking changes » par rapport à la 0.87. Une app en 0.86 ou plus ancienne cumule en revanche plusieurs montées de version, avec leurs propres changements.

Où en est Expo

Expo a pris le sujet en amont, avec un chemin par version de SDK.

SDK 58 (15 octobre 2026, React Native 0.88) est « built for iOS 27 ». npx expo prebuild génère SceneDelegate.swift et l’entrée UIApplicationSceneManifest, et la fenêtre est créée par le scene delegate (PR #46733 (nouvelle fenêtre), #46734 (nouvelle fenêtre)). Expo retransmet les événements d’URL, d’activité utilisateur, de Handoff, de cycle de vie et de quick actions aux surcharges d’ExpoAppDelegate et aux ExpoAppDelegateSubscriber, ce qui garde fonctionnels les config plugins existants (#49925 (nouvelle fenêtre), #50032 (nouvelle fenêtre)).

SDK 57 reste sur l’ancien cycle de vie par défaut. Depuis expo@57.0.23, la propriété ios.enableSceneSupport d’expo-build-properties (57.0.20 ou plus) l’active (guide Expo (nouvelle fenêtre)). Le plugin ne modifie que l’AppDelegate du template : si le vôtre diffère, ou si l’Info.plist déclare déjà un manifeste de scènes, il refuse d’écraser et la migration se fait à la main. Expo présente cette option comme un moyen de compiler avec Xcode 27 « before upgrading to SDK 58 ».

SDK 56 et antérieurs : les sources Expo ne documentent aucun chemin vers Xcode 27.

Le guide de migration Expo distingue clairement qui doit agir :

  • rien à faire pour un projet en Continuous Native Generation (nouvelle fenêtre) dont le code natif passe par des config plugins ou des modules Expo : npx expo prebuild --clean suffit ;
  • action requise si le dossier ios est maintenu à la main, pour une app React Native nue qui utilise des modules Expo (npx install-expo-modules@latest fait la migration), ou si du code surcharge directement des méthodes de UIApplicationDelegate ;
  • une librairie qui attend qu’UIKit appelle applicationDidBecomeActive(_:) sur l’app delegate doit passer à l’équivalent côté scène ou à ExpoAppDelegateSubscriber.

Côté EAS Build, l’image compte autant que le SDK. D’après la référence d’infrastructure (nouvelle fenêtre) :

AliasImageXcode
latest, sdk-58macos-tahoe-26.6-xcode-27.127.1 RC
sans aliasmacos-tahoe-26.6-xcode-27.027.0
sdk-57macos-tahoe-26.5-xcode-26.626.6
sdk-56macos-tahoe-26.4-xcode-26.426.4
auto (par défaut)choisie selon le projetselon le SDK

Sans image fixée dans eas.json, EAS utilise l’alias auto, qui choisit l’image selon la version du SDK. Pour SDK 57, la référence d’infrastructure d’Expo laisse entendre une image Xcode 26 (l’alias sdk-57 pointe vers Xcode 26.6), à vérifier dans la section « Spin up build environment » du log de build. Ce build ne passera plus en avril 2027. Pour rester sur SDK 57 avec Xcode 27, il faut activer enableSceneSupport et fixer une image Xcode 27 dans eas.json.

Deux changements de SDK 58 touchent aussi l’interface : sur iOS 26 et plus, l’en-tête de Stack d’Expo Router est transparent avec Liquid Glass par défaut et le contenu passe dessous (guide de migration Router (nouvelle fenêtre)), et expo-glass-effect renvoie isLiquidGlassAvailable à true dans les apps compilées avec le SDK iOS 27.

Vérifier son app

Cinq vérifications, à lancer à la racine du projet. Sur un projet Expo en Continuous Native Generation, générez d’abord le dossier natif avec npx expo prebuild --platform ios.

# 1. Versions de React Native et d’Expo
npm ls react-native expo

# 2. Le manifeste de scènes est-il déclaré ?
grep -c UIApplicationSceneManifest ios/*/Info.plist

# 3. L’app désactive-t-elle Liquid Glass ?
grep -rn UIDesignRequiresCompatibility ios/*/Info.plist app.json app.config.* 2>/dev/null

# 4. Callbacks d’AppDelegate qui ne seront plus appelés
grep -nE 'open url|openURL|continue userActivity|continueUserActivity|DidBecomeActive|WillResignActive|DidEnterBackground|WillEnterForeground|performActionFor' ios/*/AppDelegate.*

# 5. Image EAS fixée à la main
grep -n '"image"' eas.json

Un 0 à l’étape 2 sur une app qui sera compilée avec Xcode 27 annonce un échec au lancement. Chaque ligne de l’étape 4 est un comportement à retester sous UIScene. Faites ensuite un build avec Xcode 27 et lancez-le sur un simulateur iOS 27 : selon le guide Expo, un écran noir au démarrage signale un manifeste de scènes ou un SceneDelegate manquant, ou un UISceneDelegateClassName qui ne résout pas.

Le parcours à tester à la main après la migration : ouverture par lien profond app fermée et app ouverte, universal link, tap sur une notification push, quick action de l’icône, passage en arrière-plan puis retour, rotation et redimensionnement. Expo signale un cas précis : si Linking.getInitialURL() renvoie null au démarrage à froid, mettez à jour le package expo de SDK 58, corrigé par la PR #47628 (nouvelle fenêtre).

Et Google Play ?

Pas d’échéance comparable à court terme. Selon la page de Google (nouvelle fenêtre), depuis le 31 août 2026, « New apps and app updates must target Android 16 (API level 36) or higher », et les applications existantes doivent cibler Android 15 (API 35) pour rester disponibles pour les nouveaux utilisateurs dont l’appareil tourne sur une version d’Android supérieure à leur API cible. Les équipes qui ont demandé une extension ont jusqu’au 1er novembre 2026. Expo SDK 57 et 58 ciblent déjà l’API 36. Au 27 octobre 2026, la page ne donne aucune exigence pour 2027.

Ce qu’on recommande

Dans l’ordre.

  1. Recenser, pour chaque app, la version de React Native ou d’Expo, l’image de build EAS ou la version de Xcode de la CI, et la version de macOS des runners.
  2. Passer les Mac de build et les runners sur macOS Tahoe 26.6 ou plus, condition pour installer Xcode 27.
  3. Planifier la montée vers React Native 0.88 ou Expo SDK 58. Sur SDK 57, enableSceneSupport est une passerelle, pas une destination.
  4. Migrer l’AppDelegate vers le cycle de vie UIScene, et lister chaque librairie native qui s’accroche aux callbacks de l’app delegate : push, attribution, deep links, analytics.
  5. Retirer UIDesignRequiresCompatibility, faire une revue visuelle sous Liquid Glass, et retester les écrans à orientation verrouillée.
  6. Publier en production un build Xcode 27 bien avant avril. Notre conseil : au plus tard en février 2027, pour garder de la marge si un correctif urgent tombe au printemps.
  7. Côté Android, vérifier que chaque app cible l’API 36, surtout si elle vivait sur une extension.

Le collectif réalise cet audit si vous préférez le déléguer.

Ce qu’on ne sait pas encore

  • Le jour exact d’avril 2027. En 2026, l’exigence équivalente est entrée en vigueur le 28 avril.
  • Si React Native publiera un backport du support SceneDelegate sur 0.87 ou 0.86. Rien n’est annoncé.
  • Quand React Native prendra en charge plusieurs scènes ; la 0.88 se limite à une seule.
  • Comment chaque SDK natif tiers (push, attribution, paiement) se comporte sous UIScene dans une app React Native nue. Aucune liste consolidée n’existe.
  • Si Xcode 27 fait passer les projets existants en objectVersion = 110, et quand CocoaPods corrigera l’issue #12927.
  • L’exigence Google Play de target API pour 2027.

Ce guide sera mis à jour quand ces points seront tranchés. La date de dernière révision figure en tête de page.

Sources

Questions fréquentes

Quelle est la date exacte de l’obligation ?

Apple écrit « Starting April 2027 », sans jour. Interrogé sur les forums développeurs, un ingénieur Apple a répondu qu’Apple ne communique pas les dates exactes des futures exigences de SDK avant leur annonce officielle. L’exigence précédente, Xcode 26 et SDK iOS 26, est entrée en vigueur le 28 avril 2026. Planifiez comme si l’obligation tombait le 1er avril 2027.

Mon app publiée va-t-elle disparaître de l’App Store en avril 2027 ?

Non. L’exigence porte sur les builds envoyés sur App Store Connect. Un ingénieur Apple précise que l’obligation UIScene est liée à la compilation avec le SDK iOS 27, et que les apps compilées avec un SDK antérieur continuent de fonctionner comme avant. En revanche, à partir d’avril 2027, plus aucune mise à jour, correctif urgent compris, ne pourra être envoyée sans le SDK iOS 27.

Peut-on rester sur React Native 0.87 ou une version plus ancienne ?

Pas si vous voulez publier après avril 2027. Une app compilée avec le SDK iOS 27 sans cycle de vie UIScene ne se lance pas. React Native 0.88, sorti le 15 octobre 2026, ajoute les points d’entrée SceneDelegate. Les derniers patchs 0.87.1 et 0.86.3 ne les contiennent pas, et aucune procédure officielle n’existe pour les versions antérieures. La montée vers 0.88 est le chemin documenté pour une app React Native nue. Exception : sur Expo SDK 57 (React Native 0.86), l’option ios.enableSceneSupport permet de compiler avec Xcode 27, voir plus bas.

Mon app Expo est-elle prête ?

Sur SDK 58, npx expo prebuild génère SceneDelegate.swift et le manifeste de scènes : un projet en Continuous Native Generation n’a rien à faire de plus. Sur SDK 57, il faut expo 57.0.23 ou plus, la propriété ios.enableSceneSupport d’expo-build-properties 57.0.20 ou plus, et une image EAS en Xcode 27, puisque l’alias sdk-57 pointe vers Xcode 26.6. Pour SDK 56 et antérieurs, Expo ne documente aucun chemin vers Xcode 27.

Qu’est-ce qui change à l’écran ?

La clé UIDesignRequiresCompatibility, qui gardait l’ancienne apparence au lieu de Liquid Glass, est ignorée par le système dès que l’app est compilée pour iOS 27. Par ailleurs, selon Expo, iOS 27 rend les apps iPhone redimensionnables : requireFullScreen ne s’applique plus, et un verrouillage d’orientation peut rester sans effet tant que l’app est redimensionnable.

Et Google Play ?

Depuis le 31 août 2026, les nouvelles apps et les mises à jour doivent cibler Android 16 (API 36). Les extensions accordées courent jusqu’au 1er novembre 2026. Expo SDK 57 et 58 ciblent déjà l’API 36. L’exigence 2027 n’est pas encore publiée sur la page de Google.

Votre app est-elle prête pour Xcode 27 ?

30 minutes avec un senior pour évaluer votre montée vers React Native 0.88 ou Expo SDK 58 avant avril 2027. Gratuit.