The iOS 27 Launch Screen Rule: Four Keys or Rejection

Apple’s iOS 27 release notes convert a documentation sentence into a submission gate: “iOS and iPadOS apps built with the 27.0 SDK or later are required to include a launch screen. Your app’s Info.plist must contain one of the following keys: UILaunchStoryboardName, UILaunchStoryboards, UILaunchScreen, or UILaunchScreens. Apps that don’t include a launch screen are rejected when the App Store begins accepting apps built with the 27.0 SDK.”1

The requirement itself is old. Apple’s Xcode guide opens with “Every iOS app must provide a launch screen.”2 What arrives in iOS 27 is the consequence for ignoring it.

TL;DR

  • Apps built against the iOS 27.0 SDK or later must declare a launch screen through one of four Info.plist keys, and the App Store rejects builds that don’t.1
  • The gate is submission, not runtime. Apple’s language is “rejected when the App Store begins accepting apps built with the 27.0 SDK,” so the failure lands in App Store Connect rather than on a user’s device.1
  • The rule names iOS and iPadOS and stops there. Apple does not extend it to tvOS, visionOS, or Mac Catalyst in the same note.1 The scene life cycle mandate landing in the same cycle reads differently: its migration guide binds iOS 27, iPadOS 27, Mac Catalyst 27, tvOS 27, and visionOS 27 by name.3
  • Two keys cover a single launch screen (UILaunchScreen builds one in the property list, UILaunchStoryboardName names a storyboard file) and two cover per-URL-scheme variants (UILaunchScreens, UILaunchStoryboards). Three of the four are dictionaries; UILaunchStoryboardName alone is a string.4567
  • Projects created from recent Xcode templates already satisfy the rule, and they satisfy it through a build setting rather than a file.811 Auditing by grepping your repository for the four keys therefore misses the answer entirely.

The rule, stated precisely

Three details in Apple’s sentence carry weight, and coverage tends to blur all three.

First, the trigger is the SDK you build against, not the OS your users run. A binary compiled against iOS 26 keeps its place on the store. Rebuild with Xcode 27 to pick up anything from the new SDK and the requirement rides along.

Second, the enforcement point is App Store acceptance. Apple wrote “rejected,” which places the failure at submission review rather than at launch. That distinction separates the launch screen rule from the scene life cycle mandate shipping in the same cycle, where Apple’s wording is that apps “fail to launch.”1 One costs you a rejected build; the other costs you a dead app on a user’s phone.

Third, the scope is iOS and iPadOS. Apple’s note names those two platforms and stops. Anyone maintaining a Catalyst or tvOS target should read the requirement as unstated rather than as extended by analogy. The 27 cycle enforces plenty elsewhere, from the scene life cycle across five platforms to ImageCreator’s removal from Image Playground, but the launch screen note stays narrow.

Which of the four keys applies

Apple offers two ways to build a launch screen and two cardinalities, which produces the four keys.

UILaunchScreen configures the launch interface directly in the property list, with no storyboard file involved. Apple describes it as the way “to configure the user interface during app launch in a way that doesn’t rely on storyboards,” and it accepts child keys for the background color, image, and the visibility of the navigation bar, tab bar, and toolbar.4 For an app whose first screen is a plain background, an empty UILaunchScreen dictionary satisfies the rule. Xcode’s own build system takes that route: “When GENERATE_INFOPLIST_FILE is enabled,” INFOPLIST_KEY_UILaunchScreen_Generation “sets the value of the UILaunchScreen key in the Info.plist file to an empty dictionary.”8

UILaunchStoryboardName points at a storyboard by filename, minus the extension: a LaunchScreen.storyboard file becomes the string LaunchScreen.5 It dates to iOS 9, and it is the only one of the four that takes a string rather than a dictionary.5 Apps with a designed launch state, or any project that ships the LaunchScreen.storyboard Xcode still adds to its storyboard templates, want this key.2

The plural forms exist for one specific case, and both are dictionaries rather than arrays.67 UILaunchScreens holds three child keys: UILaunchScreenDefinitions, the array of launch screen configurations, each carrying a UILaunchScreenIdentifier; UIURLToLaunchScreenAssociations, the map from URL scheme to identifier; and UIDefaultLaunchScreen, the fallback.6 UILaunchStoryboards mirrors the shape with UILaunchStoryboardDefinitions, UIURLToLaunchStoryboardAssociations, and UIDefaultLaunchStoryboard.7 Either one lets an app opened from myapp://compose present a different launch state than the same app opened from the home screen. Apple is direct that most apps should skip them: “If you need only one launch screen, use UILaunchScreen instead.”6

The practical decision collapses to one question. If your launch screen is a storyboard, declare UILaunchStoryboardName. If it isn’t, declare UILaunchScreen. Reach for a plural key only when you already know why you need one.

The apps that are actually caught

An app created from a current Xcode template passes without anyone touching it, which is exactly why the rule is easy to dismiss and easy to get caught by. The population at risk shares one trait: nobody on the team wrote the Info.plist by hand recently.

Generated property lists are the largest category, and Xcode itself is the largest generator. Xcode 13 changed the default: projects created from several templates “no longer require configuration files such as entitlements and Info.plist files,” and you configure the fields in the target’s Info tab and the build settings editor instead.9 Cross-platform toolchains, wrapper frameworks, and build scripts that synthesize a plist at package time add a second layer, and their templates may predate UILaunchScreen entirely. Nobody reviews a file the build system writes.

Stripped plists are the second category. Launch storyboards get deleted during size optimization, during a migration away from Interface Builder, or during a cleanup that removed the last storyboard in the project and took the launch screen with it. The app kept building, so the removal looked safe.

Inherited projects are the third, and the cohort is narrower than most coverage assumes. UILaunchStoryboardName shipped in iOS 9, so a project carried forward from 2015 already holds a qualifying key.5 The apps holding none of the four are older than that: the ones still declaring launch artwork through UILaunchImages, the iOS 7.0 key Apple deprecated at iOS 13.0 with a single instruction, “UILaunchImages has been deprecated; use Xcode launch storyboards instead.”10 A UILaunchImages array is not on Apple’s list of four, so a project that still relies on it and never adopted a storyboard reference has nothing the requirement accepts. A decade of Xcode upgrades will not have added one, because nothing in the build ever failed.

Auditing an Info.plist the build system writes

Start by accepting that the file may not exist. GENERATE_INFOPLIST_FILE turns on automatic generation, and each INFOPLIST_KEY_* build setting writes one key into the plist the build produces.8 Launch screens get two of those settings: INFOPLIST_KEY_UILaunchScreen_Generation, which writes an empty UILaunchScreen dictionary, and INFOPLIST_KEY_UILaunchStoryboardName, which writes the storyboard name.8 Neither leaves anything for a text search to find. Xcode’s current iOS SwiftUI App template ships INFOPLIST_KEY_UILaunchScreen_Generation = YES in its shared settings, so a project created that way holds a compliant target with no launch screen text anywhere in the repository.11

Ask the build system instead of the filesystem:

xcodebuild -showBuildSettings \
  -project YourApp.xcodeproj -target YourApp \
  -configuration Release -sdk iphoneos 2>/dev/null \
  | grep -E "^ +(GENERATE_INFOPLIST_FILE|INFOPLIST_FILE|INFOPLIST_KEY_UILaunch)"

Run against the Ace Citizenship project on my machine, three lines come back:11

    GENERATE_INFOPLIST_FILE = YES
    INFOPLIST_FILE = Ace-Citizenship-Info.plist
    INFOPLIST_KEY_UILaunchScreen_Generation = YES

The third line is the whole compliance answer, and no file in the repository contains it. Read the output in that order. GENERATE_INFOPLIST_FILE = YES plus an INFOPLIST_KEY_UILaunch line set to YES means the build system writes the key for you: Apple gates every INFOPLIST_KEY_* setting on generation being enabled, so the same line reads as inert under GENERATE_INFOPLIST_FILE = NO, and a value of NO writes nothing either way.8 With generation off, an INFOPLIST_FILE path is where your launch screen key has to be, so open that file and look for one of the four. With generation on and a file path present, the build system merges the two and either source satisfies the requirement.8

Both flags earn their place. -configuration Release matters because App Store review sees the Release product. -sdk iphoneos matters because Xcode writes these settings per SDK on multiplatform targets: the Reps project declares INFOPLIST_KEY_UILaunchScreen_Generation three times, once each for [sdk=iphoneos*], [sdk=iphonesimulator*], and [sdk=appletv*], and Banana List declares the first two. Drop -sdk iphoneos and none of them resolves, so the key vanishes from the output and a compliant target reads as exposed.11

Then check the artifact you actually submit. In plutil -p output, two leading spaces mark a top-level key:

plutil -p YourApp.xcarchive/Products/Applications/*.app/Info.plist \
  | grep -E '^  "UILaunch'

Against a Return archive built for distribution in April, one line comes back, and the same command against a bundle with no launch screen prints nothing and exits 1:11

  "UILaunchScreen" => {

Reach for plutil rather than PlistBuddy here. Given a path that doesn’t resolve, PlistBuddy -c "Print" writes “File Doesn’t Exist, Will Create:” and an empty Dict { } to standard output and exits 0; pipe that into a grep for the launch screen keys and the only line revealing the mistake gets swallowed, leaving empty output that reads exactly like a missing key. plutil names the file it couldn’t open and exits 1.11

A repository sweep still has a job, but a smaller one than it looks: finding hand-maintained plists worth reading.

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"

Every path it prints is a candidate to check against build settings, not a target that will fail submission. On Banana List the command returns exactly one line, ./Banana List/Info.plist, and that target ships a launch screen anyway: its build settings carry INFOPLIST_KEY_UILaunchScreen_Generation, and the archived bundle contains UILaunchScreen. Without the exclusions, the same command returns 25 lines on that repository, 24 of them build artifacts inside build/, including test-runner bundles, XCTest.framework, an .xcresult log, and a watch app.11

Adding the key by hand takes a few steps rather than a text edit. Apple’s sequence: in the settings for your target, select the Info tab; in the Custom iOS Target Properties section, expand the Launch Screen key; click the Add button, type UILaunchScreen, and press Return; then select the UILaunchScreen key, click Add again, and add child keys for the appearance options you want.2 On an Xcode-generated plist, setting INFOPLIST_KEY_UILaunchScreen_Generation to YES in the target’s build settings does the same job and survives the next build.8 For a plist generated by something other than Xcode, patch the generator’s template; the next build discards anything you edit in the output.

What the rule does not say

Apple has not published a calendar date. The trigger is phrased as “when the App Store begins accepting apps built with the 27.0 SDK,” which historically falls near the fall OS release but which Apple has not committed to in writing for this cycle.1 Treat any specific date you read as inference.

Apple also has not said that existing apps stop working, that TestFlight builds are affected, or that the requirement extends beyond iOS and iPadOS. The note covers submission of new builds and nothing else.

The fix is small enough that the interesting question is not how to comply but whether you already do. For a hand-maintained project the answer is almost certainly yes. For anything with a generated plist, the answer is worth confirming with the build system before the store starts saying no.

FAQ

Does an app built from a current Xcode template already comply?

Almost certainly, and the evidence lives in build settings rather than in a file. Xcode’s iOS SwiftUI App template sets INFOPLIST_KEY_UILaunchScreen_Generation = YES in its shared settings, which writes an empty UILaunchScreen dictionary into the Info.plist the build system produces.811 Confirm it by running xcodebuild -showBuildSettings for the Release configuration with -sdk iphoneos and looking for an INFOPLIST_KEY_UILaunch line.

Why does grepping my repository for UILaunchScreen find nothing?

Because since Xcode 13, projects created from several templates carry no Info.plist on disk; Apple moved those fields into the target’s Info tab and the build settings editor.9 The launch screen arrives from INFOPLIST_KEY_UILaunchScreen_Generation or INFOPLIST_KEY_UILaunchStoryboardName at build time.8 A text search over source files cannot see either setting, and the Info.plist files it does find are usually partial fragments the build system merges, or build artifacts under build/ and DerivedData/.

Which key should I add if I genuinely have none?

UILaunchStoryboardName if you ship a LaunchScreen.storyboard, and UILaunchScreen if you don’t.45 An empty UILaunchScreen dictionary is enough for an app that launches on a plain background, which is what Xcode generates by default.8 Skip UILaunchScreens and UILaunchStoryboards unless you present different launch states for different URL schemes; Apple’s own guidance is “If you need only one launch screen, use UILaunchScreen instead.”6

Does the requirement apply to TestFlight builds?

Apple’s note does not say. It names one consequence, rejection “when the App Store begins accepting apps built with the 27.0 SDK,” and TestFlight distribution appears nowhere in it.1 Because TestFlight builds pass through App Store Connect and beta review, the safe assumption is that a build failing the requirement fails everywhere it meets review, but Apple has not written that down. Anyone depending on the answer should test a 27.0-SDK upload rather than trust either reading of the silence.

Key Takeaways

For iOS developers: - Query build settings before you grep files. Run xcodebuild -showBuildSettings -configuration Release -sdk iphoneos and look for INFOPLIST_KEY_UILaunchScreen_Generation or INFOPLIST_KEY_UILaunchStoryboardName.8 A repository text search cannot see either one. - Choose UILaunchStoryboardName if you ship a launch storyboard and UILaunchScreen if you don’t. Skip the plural keys unless you serve different launch states per URL scheme.

For teams shipping through cross-platform toolchains: - Audit the archived .app bundle with plutil -p, not the file in source control. The generator’s output is what review sees, and plutil fails loudly on a bad path where PlistBuddy prints an empty dictionary and exits 0. - Patch the plist template in your build configuration rather than the generated file, or the next build discards the fix.

For release managers: - The failure surfaces at App Store submission, not at runtime, so it costs you a review cycle rather than a production incident. Schedule the audit before the first 27.0-SDK submission, not after a rejection. - Pair the check with the scene life cycle migration, which shares the same trigger and carries a harsher penalty.


The 27 cycle keeps converting suggestions into enforcement: ImageCreator stops working, the scene life cycle becomes a launch requirement, and the launch screen becomes a submission gate. For the rest of what ships in the same SDK, see What’s New in SwiftUI for iOS 27. The full series hub is the Apple Ecosystem Series.

References


  1. Apple, iOS & iPadOS 27 Release Notes, UIKit section. Source for the launch screen requirement, under 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.plist must contain one of the following keys: UILaunchStoryboardName, UILaunchStoryboards, UILaunchScreen, or UILaunchScreens. Apps that don’t include a launch screen are rejected when the App Store begins accepting apps built with the 27.0 SDK.” Also the source for the scene life cycle wording quoted here, which appears separately under Deprecations (radar 141837548): “Apps built with the latest SDK must adopt the scene-based life cycle or they fail to launch.” That entry carries no platform list. Verified against Apple’s documentation JSON on July 25, 2026. 

  2. Apple, Specifying your app’s launch screen, Xcode documentation. Source of “Every iOS app must provide a launch screen,” the two supported methods (information property list and user interface file), and the property-list steps quoted here: select the Info tab in the settings for your target, expand the Launch Screen key in the Custom iOS Target Properties section, add the UILaunchScreen key, then add child keys for configuration options. 

  3. Apple, Transitioning to the UIKit scene-based life cycle, Apple Developer Documentation. Source of the five-platform enumeration: “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.” 

  4. Apple, UILaunchScreen, Information Property List reference. Dictionary, iOS and iPadOS 14.0 and later. Source of “to configure the user interface during app launch in a way that doesn’t rely on storyboards” and the child keys (UIColorName, UIImageName, UIImageRespectsSafeAreaInsets, UINavigationBar, UITabBar, UIToolbar). 

  5. Apple, UILaunchStoryboardName, Information Property List reference. String, iOS and iPadOS 9.0 and later (also tvOS 9.0, watchOS 2.0). Source of the filename-without-extension rule. 

  6. Apple, UILaunchScreens, Information Property List reference. Dictionary, iOS and iPadOS 14.0 and later. Source of the child keys UILaunchScreenDefinitions (the array of configurations, each with a UILaunchScreenIdentifier), UIURLToLaunchScreenAssociations, and UIDefaultLaunchScreen, and of “If you need only one launch screen, use UILaunchScreen instead.” 

  7. Apple, UILaunchStoryboards, Information Property List reference. Dictionary, iOS and iPadOS 9.0 and later. Source of the child keys UILaunchStoryboardDefinitions, UIDefaultLaunchStoryboard, and UIURLToLaunchStoryboardAssociations, and of the redirection to UILaunchStoryboardName for a single launch storyboard. 

  8. Apple, Build settings reference, Xcode documentation. Source for GENERATE_INFOPLIST_FILE (“Automatically generate an Info.plist file”), INFOPLIST_FILE (the build system “merges the values you specify in this file with other values it generates during the build process,” and “When GENERATE_INFOPLIST_FILE is enabled, the build system also includes content from build settings in the merge process”), INFOPLIST_KEY_UILaunchScreen_Generation (“sets the value of the UILaunchScreen key in the Info.plist file to an empty dictionary”), and INFOPLIST_KEY_UILaunchStoryboardName

  9. 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.plist files. 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.” 

  10. Apple, UILaunchImages, Information Property List reference. Array of dictionaries, introduced in iOS 7.0 and deprecated at iOS 13.0. Source of “UILaunchImages has been deprecated; use Xcode launch storyboards instead.” 

  11. Author’s testing on macOS 26.5.2 with Xcode 26.6 (build 17F113), July 25, 2026, against four shipping iOS projects: Ace Citizenship, Banana List, Reps, and Return. Command output reproduced verbatim. The PlistBuddy behavior was confirmed directly: /usr/libexec/PlistBuddy -c "Print" /nonexistent/Info.plist prints “File Doesn’t Exist, Will Create:” followed by Dict { } and exits 0, while plutil -p on the same path prints “The file “Info.plist” couldn’t be opened because there is no such file” and exits 1. The template setting comes from iOS SwiftUI App.xctemplate/TemplateInfo.plist in the installed Xcode toolchain. 

相关文章

UIKit's Scene Mandate: What Fails to Launch on iOS 27

Apps built with the iOS 27 SDK must adopt the UIKit scene-based life cycle or they fail to launch. The timeline, the mig…

10 分钟阅读

The @State Macro: What Xcode 27 Stops Compiling

Xcode 27 reimplements SwiftUI's @State as a Swift macro. The break lands on toolchain upgrade, not deployment target, an…

20 分钟阅读