- Published on
- 5 min read Beginner
> Fixing ITMS-90870: Missing Launch Screen When Uploading an iOS 27 Build
App Store Connect started accepting builds made with the Xcode 27 release candidate this week, and some of the first uploads are bouncing straight back. The build archives fine and validates locally, then the upload fails with this:
ITMS-90870: Missing launch screen. Apps built with the iOS 27 SDK or later must provide a launch screen using an Xcode storyboard or UILaunchScreen.
Make sure the Info.plist contains one of the following keys: UILaunchStoryboardName, UILaunchStoryboards, UILaunchScreen, UILaunchScreens.
For details, visit: https://developer.apple.com/documentation/technotes/tn3208-preparing-your-apps-launch-screen-to-meet-app-store-requirements.
The message is unusually helpful, and the fix usually takes a minute. The interesting part is figuring out why your app has no launch screen in the first place.
What Changed in iOS 27
Starting with the iOS 27 SDK, a launch screen is a hard requirement for iPhone and iPad apps. When you upload a build made with that SDK, App Store Connect checks that the app's Info.plist contains at least one of four keys: UILaunchStoryboardName, UILaunchStoryboards, UILaunchScreen, or UILaunchScreens. If none of them is there, the upload is rejected. The rule applies to apps distributed through alternative app marketplaces as well as the App Store.
Apple's explanation in TN3208 is that a launch screen goes hand in hand with modern system features like multitasking and dynamic resizing. It's the same direction as the deprecation of UIRequiresFullScreen: Apple wants every app ready to run at whatever size the system gives it.
Only those four keys count. If your project still relies on the old launch image assets, those don't satisfy the check, and you need one of the options below.
The requirement only applies to builds made with the iOS 27 SDK, so an Xcode 26 build still uploads fine. That's a short reprieve at best. Apple has already said that from April 2027, iOS and iPadOS uploads must be built with the iOS 27 SDK or later.
The Quick Fix: Let Xcode Generate the Key
For most SwiftUI projects and anything created from a recent template, the simplest fix is a build setting. With the Generate Info.plist File setting (GENERATE_INFOPLIST_FILE) enabled, turn on Launch Screen (Generation), whose underlying name is INFOPLIST_KEY_UILaunchScreen_Generation. Xcode then writes an empty UILaunchScreen dictionary into the built Info.plist, which is enough to pass the check. New SwiftUI projects have both settings on by default, which is why many apps never run into this.
Search for "Launch Screen" in your target's Build Settings, or set it in an xcconfig file:
GENERATE_INFOPLIST_FILE = YES
INFOPLIST_KEY_UILaunchScreen_Generation = YES
This works even if your target also has its own Info.plist file. Per the build settings reference, the build system merges your file with the values it generates from build settings.
An empty dictionary gives you a plain launch screen in systemBackground, which follows light and dark appearance. If you want your brand color or a logo while the app starts, configure the dictionary yourself.
Adding UILaunchScreen to Info.plist Yourself
If you maintain Info.plist by hand, or your project comes from a generator like XcodeGen or Tuist with a checked-in plist, add the key directly. It takes a dictionary, and every entry inside it is optional:
<key>UILaunchScreen</key>
<dict>
<key>UIColorName</key>
<string>LaunchBackground</string>
<key>UIImageName</key>
<string>LaunchLogo</string>
</dict>
UIColorName and UIImageName refer to a color set and an image in your asset catalog. The dictionary also accepts UIImageRespectsSafeAreaInsets, plus UINavigationBar, UITabBar, and UIToolbar entries, so the launch screen can hint at the bars your first screen shows. If you prefer Xcode's editor, open your target's Info tab and add UILaunchScreen under Custom iOS Target Properties, as described in Specifying your app's launch screen.
Using a Launch Storyboard Instead
When a solid color and an image aren't enough, use a storyboard. Create one with File > New > File from Template and choose Launch Screen, then pick it from the Launch Screen File menu in your target's General tab. What matters is that UILaunchStoryboardName ends up in the built Info.plist. If Xcode generates your Info.plist, the matching build setting is INFOPLIST_KEY_UILaunchStoryboardName.
Launch storyboards have strict rules. They can only use UIKit classes, need a single root UIView or UIViewController, and can't have custom classes, outlets, actions, or runtime attributes.
One way to end up with this error is a project that has a LaunchScreen.storyboard file but no key pointing at it, for example because someone cleared the Launch Screen File field at some point. The file sitting in your project doesn't count. The key has to be in the built Info.plist.
Checking the Build Before You Upload
Apple's suggested check is to delete the app from your device or simulator, then build and run it. Your launch screen should flash briefly before the first screen appears. If it's blank or out of date, TN3118 walks through troubleshooting it.
Since App Store Connect only cares about the key, it's also worth checking the archive itself, especially if your Info.plist is assembled by scripts or a build tool. From the folder that holds the archive:
plutil -p "MyApp.xcarchive/Products/Applications/MyApp.app/Info.plist" | grep UILaunch
If that prints nothing, the upload will fail again.
Apps made with cross-platform tools are usually fine. The current Flutter and React Native templates both set UILaunchStoryboardName to a LaunchScreen storyboard in their Info.plist. The cases to watch for are projects where that file was deleted, and hand-rolled or engine-generated Xcode projects that never had a launch screen.
Wrapping Up
ITMS-90870 looks alarming during a release, but it has one cause. Your built Info.plist is missing all four launch screen keys. Turn on the Launch Screen generation setting, add a UILaunchScreen dictionary, or point UILaunchStoryboardName at a storyboard, then confirm the key is in your archive and upload again. If you're moving a UIKit app to the iOS 27 SDK, check out adopting the scene-based life cycle too, since that's the other requirement that catches older apps this cycle.
// Continue_Learning
Xcode 27.1 Beta or Xcode 27.2 Beta: Which One Do You Need?
Apple is running two Xcode betas at once. Xcode 27.1 beta has the iPhone Duo SDK and simulator, while Xcode 27.2 beta has the 27.2 SDKs and new tooling. Here's what's in each, the known issues to watch for, and how to keep both installed.
Fixing UIKit Apps That Won't Launch on iOS 27: Adopting the Scene Life Cycle
Apps built with the iOS 27 SDK must use the UIKit scene life cycle or they fail to launch. Here's how to tell if your app is affected, add a scene manifest, and move your app delegate code into a scene delegate.
Fixing "-[OS_dispatch_mach_msg _setContext:]: unrecognized selector" on iOS 27
An app that ran fine for years suddenly hangs on the splash screen when you debug it on an iOS 27 device, with an OS_dispatch_mach_msg unrecognized selector in the console. Here is what causes it and the one-line fix.
// Stay Updated
Get notified when I publish new tutorials on Swift, SwiftUI, and iOS development. No spam, unsubscribe anytime.