Skip to content

AI & TechnologyFlutter UIScene Migration: Fix Launch Crashes on Xcode 27

Simon Dziak
Simon Dziak
Founder & developer, App369
LinkedIn
October 18, 20268 min

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

DateWhat happenedSource
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 launchFlutter docs, Apple TN3187
November 12, 2025Flutter 3.38 adds UIScene support, with an experimental automatic migrationFlutter 3.38 post, release archive
February 11, 2026Flutter 3.41: UIScene support is the default, and eligible apps are migrated automaticallyFlutter docs, release archive
April 28, 2026App Store Connect uploads must be built with Xcode 26 or laterApple upcoming requirements
September 14, 2026Xcode 27 released. Flutter apps built with it that haven't adopted UIScene fail to launchApple 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.

  1. Build with Xcode 27 and launch on a device. If it launches, open each screen once.
  2. Cold start from a push notification and from a deep link. Launch options are nil after the migration, so these are the paths most likely to break.
  3. Background and foreground the app. Check anything that used to run in applicationDidBecomeActive or applicationWillResignActive.
  4. 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

  1. Flutter docs, UIScene adoption (last updated September 14, 2026)
  2. Apple Developer, TN3187: Migrating to the UIKit scene-based life cycle
  3. Apple Developer, Upcoming requirements
  4. Apple Developer, Releases
  5. Flutter blog, What's new in Flutter 3.38
  6. Flutter release archive (macOS)

Fixed-price services

Want this done at a fixed price?

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

Tags
#flutter uiscene migration #flutter app crashes on launch xcode 27 #uiscene lifecycle required ios 27 #FlutterSceneDelegate #FlutterImplicitEngineDelegate #didInitializeImplicitFlutterEngine #UIApplicationSceneManifest flutter #enable-uiscene-migration #TN3187 flutter
Share:

Related Resources

Related guides