BS
BleepingSwift
Published on
5 min read
Beginner

> Fixing ITMS-90870: Missing Launch Screen When Uploading an iOS 27 Build

Share:

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:

JavaScript
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:

XML
<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:

Bash
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.

subscribe.sh

// Stay Updated

Get notified when I publish new tutorials on Swift, SwiftUI, and iOS development. No spam, unsubscribe anytime.

>

By subscribing, you agree to our Privacy Policy.