Key takeaways
- Apple said at WWDC25 that in the release after iOS 26, UIKit apps built with the latest SDK must use the UIScene life cycle, or they won't launch. Xcode 27, with the iOS 27 SDK, was released on September 14, 2026.
- Flutter's docs say Flutter iOS apps built with Xcode 27 that haven't adopted UIScene fail to launch on startup.
- Flutter 3.38 added UIScene support. From Flutter 3.41 (February 11, 2026), it is the default, and the Flutter CLI migrates apps with an unmodified AppDelegate automatically when you build or run.
- A custom AppDelegate needs manual changes: register plugins in didInitializeImplicitFlutterEngine instead of didFinishLaunchingWithOptions, and add an Application Scene Manifest that uses FlutterSceneDelegate to Info.plist.
- Plugins that rely on app lifecycle events such as applicationDidBecomeActive have to move to scene events, because UIKit stops calling the UI-related AppDelegate methods after the migration.
Pricing an app? Try the free app cost calculator or get a range for your project in the instant quote.
If your Flutter iOS app fails to launch after you build it with Xcode 27, the first thing to check is whether it has adopted Apple's UIScene lifecycle. Flutter's docs say Flutter apps built with Xcode 27 (the iOS 27 SDK) that haven't adopted UIScene fail to launch on startup. From Flutter 3.41, the Flutter CLI migrates apps with an unmodified AppDelegate automatically. Apps with a custom AppDelegate, or on an older Flutter, need a few manual changes to AppDelegate and Info.plist.
The facts below come from Flutter's UIScene page, Apple's technote TN3187 and Apple's release and requirements pages, as listed in the sources. I checked each one on October 18, 2026.
Disclosure: App369 is my studio. I build and fix Flutter apps on iOS and Android, and the last section mentions what I sell. Google and Apple don't pay me for anything on this page.
What changed, and when
| Date | What happened | Source |
|---|---|---|
| June 2025 (WWDC25) | Apple announces that in the release after iOS 26, UIKit apps built with the latest SDK must use the UIScene life cycle, or they won't launch | Flutter docs, Apple TN3187 |
| November 12, 2025 | Flutter 3.38 adds UIScene support, with an experimental automatic migration | Flutter 3.38 post, release archive |
| February 11, 2026 | Flutter 3.41: UIScene support is the default, and eligible apps are migrated automatically | Flutter docs, release archive |
| April 28, 2026 | App Store Connect uploads must be built with Xcode 26 or later | Apple upcoming requirements |
| September 14, 2026 | Xcode 27 released. Flutter apps built with it that haven't adopted UIScene fail to launch | Apple releases, Flutter docs |
On October 18, 2026, Apple's upcoming requirements page still listed Xcode 26 as the minimum for uploads and gave no date for Xcode 27. In my reading, you can still ship with Xcode 26 for now, but the app won't launch the first time you build it with Xcode 27 unless it has migrated.
Apple's technote says the requirement is to adopt the scene life cycle. Supporting multiple scenes is encouraged but not required.
Step 1: let Flutter migrate it
If the app is on Flutter 3.41 or later and its AppDelegate hasn't been customized, Flutter's docs say the CLI migrates it when you run flutter run or flutter build ios. On success it prints Finished migration to UIScene lifecycle. If it can't, it warns you and gives manual steps.
My advice: if the app is on an older Flutter, upgrade to the current stable first and see whether the automatic migration covers it, before changing native code by hand.
Step 2: migrate a custom AppDelegate by hand
These steps follow Flutter's UIScene page.
Register plugins in the new callback
Plugins used to be registered in application:didFinishLaunchingWithOptions:. Now the AppDelegate conforms to FlutterImplicitEngineDelegate and registers them in didInitializeImplicitFlutterEngine:
@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
}
}
If you created method channels or platform views in didFinishLaunchingWithOptions, move them into didInitializeImplicitFlutterEngine too, using engineBridge.applicationRegistrar.messenger() as the messenger. Flutter's docs warn that accessing the FlutterViewController in didFinishLaunchingWithOptions might crash your app, and say to use the FlutterImplicitEngineDelegate protocol instead.
Move UI lifecycle code to a scene delegate
After the migration, UIKit no longer calls the AppDelegate methods tied to UI state, such as applicationDidBecomeActive. If you used them, create a scene delegate and move that code to scene events. Flutter's docs say your own scene delegate must subclass FlutterSceneDelegate or conform to FlutterSceneLifeCycleProvider.
Flutter's page adds, in its plugin section, that after the migration the launch options passed to didFinishLaunchingWithOptions are nil, and that logic relying on them moves to scene:willConnectToSession:options:. My advice: look first at code that handles a notification or a URL the app was opened with.
Add the scene manifest to Info.plist
Add this inside the top-level <dict> of ios/Runner/Info.plist, as shown on Flutter's page:
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
<key>UISceneDelegateClassName</key>
<string>FlutterSceneDelegate</string>
<key>UISceneConfigurationName</key>
<string>flutter</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
If you made your own scene delegate subclass, Flutter's page says to put its name in UISceneDelegateClassName instead of FlutterSceneDelegate: $(PRODUCT_MODULE_NAME).SceneDelegate for Swift projects, SceneDelegate for Objective-C.
Plugins and add-to-app
- Plugins: Flutter's page has a separate guide for plugins that use iOS application lifecycle events. My advice: update every plugin to its latest version, then test anything that reacts to the app opening, resuming or receiving a link, such as push notifications, deep links, sign-in and payments.
- Add-to-app: if Flutter is embedded in a native iOS app, Flutter's page has its own section, including what to do if you can't subclass
FlutterSceneDelegate.
What to test
This section is my advice, not Flutter's or Apple's.
- Build with Xcode 27 and launch on a device. If it launches, open each screen once.
- Cold start from a push notification and from a deep link. Launch options are
nilafter the migration, so these are the paths most likely to break. - Background and foreground the app. Check anything that used to run in
applicationDidBecomeActiveorapplicationWillResignActive. - Ship through TestFlight first. Check the same paths on a build installed the way users get it.
Need a hand?
If a Flutter iOS app won't launch after building with Xcode 27, or broke after the UIScene migration, the App Fix Ticket covers it in two fixed-price steps. A $450 Diagnosis gives you the root cause with evidence and a fixed repair quote within 3 business days, credited toward the fix. If you go ahead, the $1,200 Fix takes 5 business days and comes as a pull request. If the iOS build itself fails, see Flutter iOS build failed after an upgrade, or send me a short description.
Frequently asked questions
- Why does my Flutter app crash on launch when built with Xcode 27?
- Flutter's UIScene page says Flutter apps built with Xcode 27 (iOS 27 SDK) that haven't adopted the UIScene lifecycle fail to launch on startup. Apple announced at WWDC25 that UIKit apps built with the SDK after iOS 26 must use the UIScene life cycle. The fix is the UIScene migration.
- Does Flutter migrate to UIScene automatically?
- From Flutter 3.41, yes, if your AppDelegate is unmodified. Run flutter run or flutter build ios, and Flutter's docs say the CLI prints "Finished migration to UIScene lifecycle" when it succeeds. With a custom AppDelegate, or on a Flutter version before 3.41, you migrate by hand.
- How do I migrate a Flutter app to UIScene by hand?
- Per Flutter's docs: make AppDelegate conform to FlutterImplicitEngineDelegate, move GeneratedPluginRegistrant registration and any method channels into didInitializeImplicitFlutterEngine, move UI lifecycle logic to a scene delegate, and add a UIApplicationSceneManifest to Info.plist with FlutterSceneDelegate as the delegate class.
- Do I have to upload with Xcode 27 now?
- Not yet, as of October 18, 2026. Apple's upcoming requirements page lists Xcode 26 with an iOS 26 SDK as the minimum for App Store Connect uploads since April 28, 2026, and doesn't name a date for Xcode 27. The crash happens as soon as you build with Xcode 27, so the migration is needed before you switch.
- Can I turn UIScene off temporarily?
- Flutter's docs say you can, by putting an underscore in front of Application Scene Manifest in Info.plist, and that the pubspec setting enable-uiscene-migration: false hides the CLI warning. In my view, both only make sense while you build with Xcode 26, because an app built with Xcode 27 without UIScene won't launch.
Sources
Fixed-price services
Want this done at a fixed price?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
Related Resources
Related guides
Flutter iOS Build Failed After an Upgrade? Fix CocoaPods and Xcode Errors (2026)
Flutter iOS build failing after upgrading Flutter, FlutterFire or Xcode? How to read the real error, then fix CocoaPods, deployment target and plugin version mismatches.
Read moreGoogle Play Requires Target API 36: The Android 16 Update
Since August 31, 2026, Google Play requires new apps and updates to target Android 16 (API level 36), with an extension to November 1, 2026. What changes when you target API 36 (edge-to-edge, predictive back, large-screen orientation), which Flutter versions target it by default, and what to test, from Google's docs checked October 18, 2026.
Read moreFlutter "Deleted Android v1 Embedding" Build Error: The Fix
Flutter removed the Android v1 embedding in Flutter 3.29 (February 12, 2025), so older projects now stop with "Build failed due to use of deleted Android v1 embedding" or a plugin error about PluginRegistry.Registrar. What the error means, how Flutter decides your app is v1, and the exact AndroidManifest and MainActivity changes, from Flutter's docs and source checked October 18, 2026.
Read more