Sitelet https://github.com/flutter/flutter/pull/190649
Skip to content

iOS: Migrate the scenario app to UIScene - #190649

Merged
cbracken merged 3 commits into
flutter:masterfrom
cbracken:migrate-scenario-to-uiscene
Aug 7, 2026
Merged

cbracken merged 3 commits into
flutter:masterfrom
cbracken:migrate-scenario-to-uiscene

Conversation

@cbracken

@cbracken cbracken commented Aug 6, 2026

Copy link
Copy Markdown
Member

Apps that haven't adopted the UIScene life cycle do not run on iOS 27.

This updates the scenarios app to include a UIApplicationSceneManifest in the app's Info.plist and moves the window setup into a SceneDelegate that subclasses FlutterSceneDelegate, similar to what we do in dev/integration_tests/ios_add2app_uiscene. We create the window from the connected UIWindowScene and make it key before calling to super, which is where the engine forwards the connection event on to plugins.

I've kept the bits that aren't UI setup in AppDelegate: the guard against --enable-software-rendering and the ContinuousTexture registration, which we register against the implicit engine rather than the one the scenario builds.

Since the window now belongs to the scene delegate rather than the application delegate, the tests that reached it via UIApplication.sharedApplication.delegate.window have been updated to use the new SceneDelegate.mainWindow instead. They assert that it is non-nil before using it: with no connected scene, presenting on the root view controller, assigning it, and rendering the layer are all silent no-ops that surface as an expectation timeout rather than as a missing window.

Because it's still there, Info_Skia.plist gets the same manifest to stay in sync with Info.plist, from which it differs only in FLTEnableImpeller; that said we no longer support a Skia backend, so I'll delete this in a followup.

Issue: #188336

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Aug 6, 2026
@github-actions github-actions Bot added the engine flutter/engine related. See also e: labels. label Aug 6, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request transitions the iOS scenario app to the UIScene lifecycle by introducing SceneDelegate and updating the application manifests. The window and root view controller initialization logic is moved from AppDelegate to SceneDelegate, and the test files are updated to access the window via SceneDelegate.mainWindow. The review feedback identifies two instances in SceneDelegate.m where a nullable message parameter is deserialized using NSJSONSerialization without a null check, which could lead to application crashes.

Apps that haven't adopted the UIScene life cycle do not run on iOS 27.

This updates the scenarios app to include a `UIApplicationSceneManifest`
in the app's `Info.plist` and moves the window setup into a
`SceneDelegate` that subclasses `FlutterSceneDelegate`, similar to what
we do in `dev/integration_tests/ios_add2app_uiscene`. We create the
window from the connected `UIWindowScene` and make it key before calling
to super, which is where the engine forwards the connection event on to
plugins.

I've kept the bits that aren't UI setup in `AppDelegate`: the guard
against `--enable-software-rendering` and the `ContinuousTexture`
registration, which we register against the implicit engine rather than
the one the scenario builds.

Since the window now belongs to the scene delegate rather than the
application delegate, the tests that reached it via
`UIApplication.sharedApplication.delegate.window` have been updated to
use the new `SceneDelegate.mainWindow` instead. They assert that it is
non-nil before using it: with no connected scene, presenting on the root
view controller, assigning it, and rendering the layer are all silent
no-ops that surface as an expectation timeout rather than as a missing
window.

Because it's still there, `Info_Skia.plist` gets the same manifest to
stay in sync with `Info.plist`, from which it differs only in
`FLTEnableImpeller`; that said we no longer support a Skia backend, so
I'll delete this in a followup.

Issue: flutter#188336
@cbracken
cbracken force-pushed the migrate-scenario-to-uiscene branch from ddb33e6 to b83b33a Compare August 6, 2026 21:23

@hellohuanlin hellohuanlin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@cbracken
cbracken enabled auto-merge August 6, 2026 22:39
@cbracken
cbracken added this pull request to the merge queue Aug 7, 2026
Merged via the queue into flutter:master with commit d4e7f9a Aug 7, 2026
17 checks passed
@cbracken
cbracken deleted the migrate-scenario-to-uiscene branch August 7, 2026 04:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD engine flutter/engine related. See also e: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants