Repository navigation
Description
Steps to reproduce
This came up when reading:
flutter/dev/devicelab/bin/tasks/module_uiscene_test_ios.dart
Lines 612 to 616 in 987d8c5
| // When using an implicit FlutterEngine, created by the FlutterViewController in another | |
| // ViewController, we expect plugins to be registered after the FlutterViewController is | |
| // created, which results in the `application:didFinishLaunchingWithOptions:` and | |
| // `scene:willConnectToSession:options:` events being missed. This is not a expected use case | |
| // but it could be utilized. |
For didFinishLaunching
The old behavior before UIScene migration is that, if FlutterViewController is created programmatically, even if it's created as child of the rootVC (like what this integration test is doing), plugins still won't receive didFinishLaunching event, because rootVC's viewDidLoad is called after didFinishLaunching returns.
However, if FlutterViewController is created from storyboard (again, as child of the rootVC), plugins will receive didFinishLaunching event.
This behavior is odd, but since it's been this way, we should keep it untouched.
For sceneWillConnect
First of all, there's no original behavior before UIScene migration (sceneWillConnect is only applicable after UIScene migration)
From my observation, the current behavior for FlutterViewController created as the child of the rootVC:
- If FlutterViewController is created programmatically:
- If engine is created in app delegate's didFinishLaunching, plugins will receive
sceneWillConnect - If engine is created afterwards, plugins won't receive
sceneWillConnect
- If engine is created in app delegate's didFinishLaunching, plugins will receive
- If FlutterViewController is created from Storyboard, then plugins will always receive
sceneWillConnect.
(for both cases above, FlutterViewController is created as a child of the rootVC)
This behavior is a bit confusing and can be brittle:
- If a developer makes
FlutterViewControllera child of the rootVC, the intention is to receivesceneWillConnect, regardless whether they use storyboard or not. - The fact that Apple changed storyboard loading order once (and caused so much headache) hinted that the current setup is quite brittle, and could very well cause more headache down the road.
Proposal
The only factor that matters here is: "when is FlutterViewController added to the scene?" - if it's added in the same run-loop as scene connection, we should pipe sceneWillConnect; if it's added afterwards, we should not pipe sceneWillConnect. Using storyboard or not should be irrelevant.
In this particular case, where a developer makes FlutterViewController a child of the rootVC, we should always pipe sceneWillConnect, regardless of using storyboard or not.
Why not just check if VC is added before sceneWillConnect is called?
Because for some scenarios (e.g. SwiftUI), VC is added after sceneWillConnect is called. But it still happens in the same run-loop.
Can we just use scene connection's notification?
Note that scene connection notification is sent after sceneWillConnect is called, but before viewDidLoad of rootVC is called. So if we rely on the notification will also miss some edge cases.
The simplest approach is to rely on willEnterForeground and didEnterBackground, which is called after view is loaded, which is the best timing to capture this edge case. The drawback would be that it's called with a delay. However, it's still on the same run-loop (just like the connection notification path).
Activity
saurabh-mirajkar commentedon May 18, 2026
@hellohuanlin Thanks for the report. Routing to
team-iosto investigate further.vashworth commentedon May 18, 2026
I can't remember if this was actually a problem or just a use case I added tests for. We should test it without the UIScene migration to see if pre-UIScene received the
didFinishLaunchingevent. If it didn't, then I think we can just close this.hellohuanlin commentedon May 18, 2026
In pre-UIScene, when using storyboard,FlutterViewControlleris loaded beforedidFinishLaunchingis called. See the first 2 diagrams from: https://docs.google.com/document/d/1ZfcQOs-UKRa9jsFG84-MTFeibZTLKCvPQLxF2eskx44/edit?tab=t.0Oh I may have looked at the wrong case - you are talking about the non-storyboard case.
[-][UIScene] Using implicit engine misses didFinishLaunching & willConnectScene events[/-][+][UIScene] Using implicit engine misses willConnectScene event[/+]hellohuanlin commentedon May 19, 2026
@vashworth I tried out the pre-migration behavior, and confirmed
didFinishLaunchingis not called in this case. ThoughsceneWillConnectis another story (as there was no "pre-migration" behavior), and I find the current behavior a bit confusing and can be brittle. I updated the issue with more info.[ios] Use DFS traversal to find engines of a scene automatically (rat…
[ios] Use DFS traversal to find engines of a scene automatically (rat…
github-actions commentedon Oct 30, 2026
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.