La regla de la pantalla de inicio en iOS 27: cuatro claves o rechazo
Las notas de la versión de iOS 27 convierten una frase de la documentación en un filtro de envío: “Las apps de iOS e iPadOS compiladas con el SDK 27.0 o posterior deben incluir una pantalla de inicio. El Info.plist de tu app debe contener una de las siguientes claves: UILaunchStoryboardName, UILaunchStoryboards, UILaunchScreen o UILaunchScreens. Las apps que no incluyan una pantalla de inicio se rechazan cuando la App Store empiece a aceptar apps compiladas con el SDK 27.0”.1
El requisito en sí no es nuevo. La guía de Xcode de Apple abre con “Toda app de iOS debe proporcionar una pantalla de inicio”.2 Lo que llega con iOS 27 es la consecuencia de ignorarlo.
En resumen
- Las apps compiladas contra el SDK de iOS 27.0 o posterior deben declarar una pantalla de inicio mediante una de cuatro claves de
Info.plist, y la App Store rechaza las compilaciones que no lo hagan.1 - El filtro está en el envío, no en tiempo de ejecución. Apple habla de compilaciones “rechazadas cuando la App Store empiece a aceptar apps compiladas con el SDK 27.0”, así que la falla aparece en App Store Connect y no en el dispositivo de un usuario.1
- La regla nombra iOS e iPadOS y ahí se detiene. Apple no la extiende a tvOS, visionOS ni Mac Catalyst en la misma nota.1 El mandato del ciclo de vida basado en escenas que aterriza en el mismo ciclo se lee distinto: su guía de migración nombra explícitamente a iOS 27, iPadOS 27, Mac Catalyst 27, tvOS 27 y visionOS 27.3
- Dos claves cubren una única pantalla de inicio (
UILaunchScreenla construye dentro de la lista de propiedades,UILaunchStoryboardNamenombra un archivo de storyboard) y dos cubren variantes por esquema de URL (UILaunchScreens,UILaunchStoryboards). Tres de las cuatro son diccionarios; soloUILaunchStoryboardNamees una cadena.4567 - Los proyectos creados con las plantillas recientes de Xcode ya cumplen la regla, y lo hacen mediante un ajuste de compilación en lugar de un archivo.811 Auditar buscando las cuatro claves con grep en tu repositorio, por tanto, no encuentra la respuesta en absoluto.
La regla, dicha con precisión
Hay tres detalles con peso en la frase de Apple, y la cobertura del tema suele difuminar los tres.
Primero, lo que dispara el requisito es el SDK contra el que compilas, no el sistema operativo que usan tus usuarios. Un binario compilado contra iOS 26 conserva su lugar en la tienda. Vuelve a compilarlo con Xcode 27 para aprovechar cualquier novedad del nuevo SDK y el requisito viaja con él.
Segundo, el punto de aplicación es la aceptación en la App Store. Apple escribió “rechazadas”, lo que sitúa la falla en la revisión del envío y no en el arranque. Esa distinción separa la regla de la pantalla de inicio del mandato del ciclo de vida basado en escenas que llega en el mismo ciclo, donde la redacción de Apple es que las apps “no arrancan”.1 Una te cuesta una compilación rechazada; la otra, una app muerta en el teléfono de un usuario.
Tercero, el alcance es iOS e iPadOS. La nota de Apple nombra esas dos plataformas y se detiene. Quien mantenga un target de Catalyst o tvOS debería leer el requisito como no declarado, no como extendido por analogía. El ciclo 27 impone bastantes cosas en otros frentes, desde el ciclo de vida basado en escenas en cinco plataformas hasta la eliminación de ImageCreator de Image Playground, pero la nota de la pantalla de inicio se mantiene estrecha.
Cuál de las cuatro claves te toca
Apple ofrece dos formas de construir una pantalla de inicio y dos cardinalidades, y de ahí salen las cuatro claves.
UILaunchScreen configura la interfaz de arranque directamente en la lista de propiedades, sin ningún archivo de storyboard de por medio. Apple la describe como la forma de “configurar la interfaz de usuario durante el arranque de la app sin depender de storyboards”, y acepta claves hijas para el color de fondo, la imagen y la visibilidad de la barra de navegación, la barra de pestañas y la barra de herramientas.4 Para una app cuya primera pantalla es un fondo liso, un diccionario UILaunchScreen vacío cumple la regla. El propio sistema de compilación de Xcode toma esa ruta: “Cuando GENERATE_INFOPLIST_FILE está habilitado”, INFOPLIST_KEY_UILaunchScreen_Generation “asigna al valor de la clave UILaunchScreen del archivo Info.plist un diccionario vacío”.8
UILaunchStoryboardName apunta a un storyboard por nombre de archivo, sin la extensión: un archivo LaunchScreen.storyboard se convierte en la cadena LaunchScreen.5 Viene de iOS 9 y es la única de las cuatro que recibe una cadena en lugar de un diccionario.5 Las apps con un estado de arranque diseñado, o cualquier proyecto que incluya el LaunchScreen.storyboard que Xcode sigue agregando a sus plantillas con storyboards, quieren esta clave.2
Las formas plurales existen para un caso muy concreto, y ambas son diccionarios, no arreglos.67 UILaunchScreens contiene tres claves hijas: UILaunchScreenDefinitions, el arreglo de configuraciones de pantalla de inicio, cada una con su UILaunchScreenIdentifier; UIURLToLaunchScreenAssociations, el mapa de esquema de URL a identificador; y UIDefaultLaunchScreen, la opción por defecto.6 UILaunchStoryboards refleja la misma forma con UILaunchStoryboardDefinitions, UIURLToLaunchStoryboardAssociations y UIDefaultLaunchStoryboard.7 Cualquiera de las dos permite que una app abierta desde myapp://compose muestre un estado de arranque distinto al de la misma app abierta desde la pantalla de inicio del dispositivo. Apple es directa al decir que la mayoría de las apps deberían saltárselas: “Si solo necesitas una pantalla de inicio, usa UILaunchScreen en su lugar”.6
En la práctica, la decisión se reduce a una sola pregunta. Si tu pantalla de inicio es un storyboard, declara UILaunchStoryboardName. Si no lo es, declara UILaunchScreen. Recurre a una clave plural únicamente cuando ya sepas por qué la necesitas.
Las apps que sí quedan atrapadas
Una app creada con una plantilla actual de Xcode pasa sin que nadie toque nada, y por eso mismo la regla es fácil de descartar y fácil de sufrir. La población en riesgo comparte un rasgo: nadie del equipo escribió el Info.plist a mano en los últimos tiempos.
Las listas de propiedades generadas son la categoría más grande, y el mayor generador es el propio Xcode. Xcode 13 cambió el comportamiento por defecto: los proyectos creados a partir de varias plantillas “ya no requieren archivos de configuración como los entitlements ni los archivos Info.plist”, y en su lugar configuras los campos en la pestaña Info del target y en el editor de ajustes de compilación.9 Las cadenas de herramientas multiplataforma, los frameworks envoltorio y los scripts de compilación que sintetizan un plist al empaquetar agregan una segunda capa, y sus plantillas pueden ser anteriores a la existencia misma de UILaunchScreen. Nadie revisa un archivo que escribe el sistema de compilación.
Los plists recortados son la segunda categoría. Los storyboards de arranque se borran durante una optimización de tamaño, durante una migración que abandona Interface Builder o durante una limpieza que eliminó el último storyboard del proyecto y se llevó la pantalla de inicio consigo. La app siguió compilando, así que la eliminación pareció segura.
Los proyectos heredados son la tercera, y el grupo es más reducido de lo que suele suponerse. UILaunchStoryboardName llegó con iOS 9, así que un proyecto que viene desde 2015 ya tiene una clave válida.5 Las apps que no tienen ninguna de las cuatro son más viejas que eso: las que todavía declaran las imágenes de arranque mediante UILaunchImages, la clave de iOS 7.0 que Apple marcó como obsoleta en iOS 13.0 con una sola instrucción: “UILaunchImages ha quedado obsoleta; usa los storyboards de arranque de Xcode en su lugar”.10 Un arreglo UILaunchImages no está en la lista de cuatro de Apple, así que un proyecto que todavía dependa de él y nunca haya adoptado una referencia a storyboard no tiene nada que el requisito acepte. Una década de actualizaciones de Xcode no le habrá agregado ninguna, porque nada en la compilación falló jamás.
Cómo auditar un Info.plist que escribe el sistema de compilación
Empieza por aceptar que quizá el archivo no exista. GENERATE_INFOPLIST_FILE activa la generación automática, y cada ajuste de compilación INFOPLIST_KEY_* escribe una clave en el plist que produce la compilación.8 A las pantallas de inicio les corresponden dos de esos ajustes: INFOPLIST_KEY_UILaunchScreen_Generation, que escribe un diccionario UILaunchScreen vacío, e INFOPLIST_KEY_UILaunchStoryboardName, que escribe el nombre del storyboard.8 Ninguno deja nada que una búsqueda de texto pueda encontrar. La plantilla actual de app SwiftUI para iOS de Xcode trae INFOPLIST_KEY_UILaunchScreen_Generation = YES en sus ajustes compartidos, de modo que un proyecto creado así tiene un target que cumple sin que exista texto alguno sobre la pantalla de inicio en el repositorio.11
Pregúntale al sistema de compilación, no al sistema de archivos:
xcodebuild -showBuildSettings \
-project YourApp.xcodeproj -target YourApp \
-configuration Release -sdk iphoneos 2>/dev/null \
| grep -E "^ +(GENERATE_INFOPLIST_FILE|INFOPLIST_FILE|INFOPLIST_KEY_UILaunch)"
Ejecutado contra el proyecto Ace Citizenship en mi máquina, devuelve tres líneas:11
GENERATE_INFOPLIST_FILE = YES
INFOPLIST_FILE = Ace-Citizenship-Info.plist
INFOPLIST_KEY_UILaunchScreen_Generation = YES
La tercera línea es toda la respuesta sobre cumplimiento, y ningún archivo del repositorio la contiene. Lee la salida en ese orden. GENERATE_INFOPLIST_FILE = YES más una línea INFOPLIST_KEY_UILaunch puesta en YES significa que el sistema de compilación escribe la clave por ti: Apple condiciona todos los ajustes INFOPLIST_KEY_* a que la generación esté habilitada, así que esa misma línea queda inerte bajo GENERATE_INFOPLIST_FILE = NO, y un valor de NO no escribe nada en ninguno de los dos casos.8 Con la generación desactivada, la ruta de INFOPLIST_FILE es donde tiene que estar tu clave de pantalla de inicio, así que abre ese archivo y busca una de las cuatro. Con la generación activada y además una ruta de archivo presente, el sistema de compilación fusiona ambas y cualquiera de las dos fuentes satisface el requisito.8
Ambas opciones se ganan su lugar. -configuration Release importa porque la revisión de la App Store ve el producto Release. -sdk iphoneos importa porque Xcode escribe estos ajustes por SDK en los targets multiplataforma: el proyecto Reps declara INFOPLIST_KEY_UILaunchScreen_Generation tres veces, una para [sdk=iphoneos*], otra para [sdk=iphonesimulator*] y otra para [sdk=appletv*], y Banana List declara las dos primeras. Quita -sdk iphoneos y ninguna de ellas se resuelve, así que la clave desaparece de la salida y un target que cumple se lee como expuesto.11
Después revisa el artefacto que realmente envías. En la salida de plutil -p, dos espacios iniciales marcan una clave de nivel superior:
plutil -p YourApp.xcarchive/Products/Applications/*.app/Info.plist \
| grep -E '^ "UILaunch'
Contra un archive de Return compilado para distribución en abril, vuelve una sola línea, y el mismo comando contra un bundle sin pantalla de inicio no imprime nada y sale con código 1:11
"UILaunchScreen" => {
Aquí conviene recurrir a plutil y no a PlistBuddy. Ante una ruta que no se resuelve, PlistBuddy -c "Print" escribe “File Doesn’t Exist, Will Create:” y un Dict { } vacío en la salida estándar y sale con código 0; canaliza eso hacia un grep de las claves de pantalla de inicio y la única línea que delataría el error se pierde, dejando una salida vacía que se lee exactamente igual que una clave faltante. plutil nombra el archivo que no pudo abrir y sale con código 1.11
Un barrido del repositorio sigue teniendo su función, pero más modesta de lo que parece: encontrar los plists mantenidos a mano que vale la pena leer.
find . -name "Info.plist" \
-not -path "*/build/*" -not -path "*/DerivedData/*" \
-not -path "*/.build/*" -not -path "*/Carthage/*" -not -path "*/Pods/*" \
-print0 | xargs -0 grep -L -E "UILaunchScreen|UILaunchStoryboard"
Cada ruta que imprime es una candidata a contrastar con los ajustes de compilación, no un target que vaya a fallar en el envío. En Banana List el comando devuelve exactamente una línea, ./Banana List/Info.plist, y ese target incluye una pantalla de inicio de todos modos: sus ajustes de compilación llevan INFOPLIST_KEY_UILaunchScreen_Generation, y el bundle archivado contiene UILaunchScreen. Sin las exclusiones, el mismo comando devuelve 25 líneas en ese repositorio, 24 de ellas artefactos de compilación dentro de build/, incluidos bundles de test runner, XCTest.framework, un registro .xcresult y una app de Apple Watch.11
Agregar la clave a mano lleva unos cuantos pasos, no una edición de texto. La secuencia de Apple: en los ajustes de tu target, selecciona la pestaña Info; en la sección Custom iOS Target Properties, expande la clave Launch Screen; haz clic en el botón Add, escribe UILaunchScreen y presiona Return; luego selecciona la clave UILaunchScreen, vuelve a hacer clic en Add y agrega las claves hijas de las opciones de apariencia que quieras.2 En un plist generado por Xcode, poner INFOPLIST_KEY_UILaunchScreen_Generation en YES dentro de los ajustes de compilación del target hace lo mismo y sobrevive a la siguiente compilación.8 Para un plist generado por algo que no sea Xcode, parchea la plantilla del generador; la siguiente compilación descarta cualquier cosa que edites en la salida.
Lo que la regla no dice
Apple no ha publicado una fecha de calendario. El disparador se formula como “cuando la App Store empiece a aceptar apps compiladas con el SDK 27.0”, momento que históricamente cae cerca del lanzamiento del sistema operativo en otoño, pero que Apple no ha fijado por escrito para este ciclo.1 Toma cualquier fecha concreta que leas por ahí como una inferencia.
Apple tampoco ha dicho que las apps existentes dejen de funcionar, que las compilaciones de TestFlight se vean afectadas, ni que el requisito vaya más allá de iOS e iPadOS. La nota cubre el envío de compilaciones nuevas y nada más.
La corrección es lo bastante pequeña como para que la pregunta interesante no sea cómo cumplir, sino si ya cumples. En un proyecto mantenido a mano la respuesta es casi con certeza que sí. En cualquier cosa con un plist generado, vale la pena confirmarlo con el sistema de compilación antes de que la tienda empiece a decir que no.
Preguntas frecuentes
¿Una app creada con una plantilla actual de Xcode ya cumple?
Casi con certeza, y la evidencia vive en los ajustes de compilación, no en un archivo. La plantilla de app SwiftUI para iOS de Xcode fija INFOPLIST_KEY_UILaunchScreen_Generation = YES en sus ajustes compartidos, lo que escribe un diccionario UILaunchScreen vacío en el Info.plist que produce el sistema de compilación.811 Confírmalo ejecutando xcodebuild -showBuildSettings para la configuración Release con -sdk iphoneos y buscando una línea INFOPLIST_KEY_UILaunch.
¿Por qué buscar UILaunchScreen con grep en mi repositorio no encuentra nada?
Porque desde Xcode 13 los proyectos creados a partir de varias plantillas no llevan ningún Info.plist en disco; Apple movió esos campos a la pestaña Info del target y al editor de ajustes de compilación.9 La pantalla de inicio llega desde INFOPLIST_KEY_UILaunchScreen_Generation o INFOPLIST_KEY_UILaunchStoryboardName en tiempo de compilación.8 Una búsqueda de texto sobre los archivos fuente no puede ver ninguno de esos ajustes, y los archivos Info.plist que sí encuentra suelen ser fragmentos parciales que el sistema de compilación fusiona, o artefactos de compilación bajo build/ y DerivedData/.
¿Qué clave debo agregar si de verdad no tengo ninguna?
UILaunchStoryboardName si incluyes un LaunchScreen.storyboard, y UILaunchScreen si no.45 Un diccionario UILaunchScreen vacío basta para una app que arranca sobre un fondo liso, que es lo que Xcode genera por defecto.8 Sáltate UILaunchScreens y UILaunchStoryboards a menos que presentes estados de arranque distintos para distintos esquemas de URL; la propia recomendación de Apple es: “Si solo necesitas una pantalla de inicio, usa UILaunchScreen en su lugar”.6
¿El requisito aplica a las compilaciones de TestFlight?
La nota de Apple no lo dice. Menciona una sola consecuencia, el rechazo “cuando la App Store empiece a aceptar apps compiladas con el SDK 27.0”, y la distribución por TestFlight no aparece en ninguna parte.1 Como las compilaciones de TestFlight pasan por App Store Connect y por la revisión beta, lo prudente es suponer que una compilación que incumple el requisito falla en todos los lugares donde se topa con una revisión, pero Apple no lo ha puesto por escrito. Quien dependa de la respuesta debería probar una subida con el SDK 27.0 en lugar de confiar en cualquiera de las dos lecturas del silencio.
Conclusiones clave
Para desarrolladores de iOS:
- Consulta los ajustes de compilación antes de hacer grep en los archivos. Ejecuta xcodebuild -showBuildSettings -configuration Release -sdk iphoneos y busca INFOPLIST_KEY_UILaunchScreen_Generation o INFOPLIST_KEY_UILaunchStoryboardName.8 Una búsqueda de texto en el repositorio no puede ver ninguno de los dos.
- Elige UILaunchStoryboardName si incluyes un storyboard de arranque y UILaunchScreen si no. Sáltate las claves plurales salvo que sirvas estados de arranque distintos por esquema de URL.
Para equipos que publican con cadenas de herramientas multiplataforma:
- Audita el bundle .app archivado con plutil -p, no el archivo que está en control de versiones. Lo que ve la revisión es la salida del generador, y plutil falla ruidosamente ante una ruta incorrecta, mientras que PlistBuddy imprime un diccionario vacío y sale con código 0.
- Parchea la plantilla del plist en tu configuración de compilación en lugar del archivo generado, o la siguiente compilación descartará la corrección.
Para responsables de lanzamiento: - La falla aparece en el envío a la App Store, no en tiempo de ejecución, así que te cuesta un ciclo de revisión y no un incidente en producción. Programa la auditoría antes del primer envío con el SDK 27.0, no después de un rechazo. - Combina la revisión con la migración al ciclo de vida basado en escenas, que comparte el mismo disparador y trae un castigo más duro.
El ciclo 27 sigue convirtiendo sugerencias en obligaciones: ImageCreator deja de funcionar, el ciclo de vida basado en escenas se vuelve un requisito de arranque y la pantalla de inicio se vuelve un filtro de envío. Para el resto de lo que llega en el mismo SDK, mira Novedades de SwiftUI en iOS 27. El centro de toda la serie es la Serie sobre el ecosistema Apple.
Referencias
-
Apple, iOS & iPadOS 27 Release Notes, sección UIKit. Fuente del requisito de la pantalla de inicio, en New Features (radar 168247372): “iOS and iPadOS apps built with the 27.0 SDK or later are required to include a launch screen. Your app’s
Info.plistmust contain one of the following keys:UILaunchStoryboardName,UILaunchStoryboards,UILaunchScreen, orUILaunchScreens. Apps that don’t include a launch screen are rejected when the App Store begins accepting apps built with the 27.0 SDK”. También es la fuente de la redacción sobre el ciclo de vida basado en escenas citada aquí, que aparece por separado en Deprecations (radar 141837548): “Apps built with the latest SDK must adopt the scene-based life cycle or they fail to launch”. Esa entrada no incluye lista de plataformas. Verificado contra el JSON de documentación de Apple el 25 de julio de 2026. ↩↩↩↩↩↩↩ -
Apple, Specifying your app’s launch screen, documentación de Xcode. Fuente de “Every iOS app must provide a launch screen”, de los dos métodos admitidos (lista de propiedades de información y archivo de interfaz de usuario) y de los pasos con la lista de propiedades citados aquí: seleccionar la pestaña Info en los ajustes del target, expandir la clave Launch Screen en la sección Custom iOS Target Properties, agregar la clave
UILaunchScreeny luego agregar las claves hijas de las opciones de configuración. ↩↩↩ -
Apple, Transitioning to the UIKit scene-based life cycle, documentación para desarrolladores de Apple. Fuente de la enumeración de las cinco plataformas: “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, UILaunchScreen, referencia de Information Property List. Diccionario, iOS e iPadOS 14.0 y posteriores. Fuente de “to configure the user interface during app launch in a way that doesn’t rely on storyboards” y de las claves hijas (
UIColorName,UIImageName,UIImageRespectsSafeAreaInsets,UINavigationBar,UITabBar,UIToolbar). ↩↩↩ -
Apple, UILaunchStoryboardName, referencia de Information Property List. Cadena, iOS e iPadOS 9.0 y posteriores (también tvOS 9.0, watchOS 2.0). Fuente de la regla del nombre de archivo sin extensión. ↩↩↩↩↩
-
Apple, UILaunchScreens, referencia de Information Property List. Diccionario, iOS e iPadOS 14.0 y posteriores. Fuente de las claves hijas
UILaunchScreenDefinitions(el arreglo de configuraciones, cada una con unUILaunchScreenIdentifier),UIURLToLaunchScreenAssociationsyUIDefaultLaunchScreen, y de “If you need only one launch screen, useUILaunchScreeninstead”. ↩↩↩↩↩ -
Apple, UILaunchStoryboards, referencia de Information Property List. Diccionario, iOS e iPadOS 9.0 y posteriores. Fuente de las claves hijas
UILaunchStoryboardDefinitions,UIDefaultLaunchStoryboardyUIURLToLaunchStoryboardAssociations, y de la redirección aUILaunchStoryboardNamepara un único storyboard de arranque. ↩↩↩ -
Apple, Build settings reference, documentación de Xcode. Fuente de
GENERATE_INFOPLIST_FILE(“Automatically generate an Info.plist file”),INFOPLIST_FILE(el sistema de compilación “merges the values you specify in this file with other values it generates during the build process”, y “WhenGENERATE_INFOPLIST_FILEis enabled, the build system also includes content from build settings in the merge process”),INFOPLIST_KEY_UILaunchScreen_Generation(“sets the value of theUILaunchScreenkey in the Info.plist file to an empty dictionary”) eINFOPLIST_KEY_UILaunchStoryboardName. ↩↩↩↩↩↩↩↩↩↩↩ -
Apple, Xcode 13 Release Notes, Templates, Resolved Issues (radar 68254857): “Projects created from several templates no longer require configuration files such as entitlements and
Info.plistfiles. Configure common fields in the target’s Info tab, and build settings in the project editor. These files are added to the project when additional fields are used”. ↩↩ -
Apple, UILaunchImages, referencia de Information Property List. Arreglo de diccionarios, introducida en iOS 7.0 y obsoleta desde iOS 13.0. Fuente de “
UILaunchImageshas been deprecated; use Xcode launch storyboards instead”. ↩ -
Pruebas del autor en macOS 26.5.2 con Xcode 26.6 (build 17F113), 25 de julio de 2026, contra cuatro proyectos de iOS en producción: Ace Citizenship, Banana List, Reps y Return. Salida de los comandos reproducida textualmente. El comportamiento de
PlistBuddyse confirmó directamente:/usr/libexec/PlistBuddy -c "Print" /nonexistent/Info.plistimprime “File Doesn’t Exist, Will Create:” seguido deDict { }y sale con código 0, mientras queplutil -psobre la misma ruta imprime “The file “Info.plist” couldn’t be opened because there is no such file” y sale con código 1. El ajuste de la plantilla proviene deiOS SwiftUI App.xctemplate/TemplateInfo.plisten la cadena de herramientas de Xcode instalada. ↩↩↩↩↩↩↩↩