[iOS] Fix implicit engine missing didFinishLaunching and sceneWillConnect events#186558
[iOS] Fix implicit engine missing didFinishLaunching and sceneWillConnect events#186558dhananjay6561 wants to merge 3 commits into
Conversation
…nect events When a FlutterViewController is created programmatically inside another view controller using an implicit engine, UISceneWillConnectNotification and application:didFinishLaunchingWithOptions: fire before the engine exists. Plugins registered via the implicit engine callback miss both events. Remove the awokenFromNib guard on the didFinishLaunching fallback so it fires for programmatic creation too (the method is idempotent). After plugin registration, iterate already-connected scenes and call engine:receivedConnectNotificationFor: so scene:willConnectToSession:options: is replayed to the engine's plugins. The storyboard (awokenFromNib) path is unaffected: awakeFromNib runs before scene:willConnectToSession: fires, so connectedScenes is empty at that point and the loop is a no-op. Fixes flutter#186547
|
It looks like this pull request may not have tests. Please make sure to add tests or get an explicit test exemption before merging. If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. If you believe this PR qualifies for a test exemption, contact "@test-exemption-reviewer" in the #hackers channel in Discord (don't just cc them here, they won't see it!). The test exemption team is a small volunteer group, so all reviewers should feel empowered to ask for tests, without delegating that responsibility entirely to the test exemption group. |
There was a problem hiding this comment.
Code Review
This pull request updates the lifecycle event handling for implicit Flutter engines on iOS to ensure plugins correctly receive application launch and scene connection events. Specifically, it modifies FlutterViewController to forward launch events for programmatic view controllers and manually registers engines with existing scenes. A review comment identified a potential runtime crash on iOS versions earlier than 13.0 because scene-specific properties are accessed without verifying scene delegate support.
|
Added |
|
Added unit tests in
|
| // launch events fire (storyboard-based VCs load before scene connect; programmatic VCs created | ||
| // inside another VC load even later). Plugins registered via the implicit engine callback will | ||
| // have missed didFinishLaunching. Forward it here if it hasn't been sent yet. | ||
| if (performedCallback && FlutterSharedApplication.hasSceneDelegate && |
There was a problem hiding this comment.
Hmmmm, from reading the code, checking self.awokenFromNib seems to be intended so removing it may cause regression.
Can you leave this part untouched for this PR, and only fix the sceneWillConnect part?
Fixes #186547
Problem
When a
FlutterViewControlleris created programmatically inside another view controller (implicit engine, non-nib path), bothUISceneWillConnectNotificationandapplication:didFinishLaunchingWithOptions:fire before the engine exists. Plugins registered viaFlutterImplicitEngineDelegate.didInitializeImplicitFlutterEngine:never receive either event.The
didFinishLaunchingfallback insharedSetupWithProject:initialRoute:was gated onawokenFromNib, so it only ran for storyboard-basedFlutterViewControllers. ThesceneWillConnectevent had no replay mechanism for this code path at all.Fix
awokenFromNibguard from thedidFinishLaunchingfallback.sceneFallbackWillFinishLaunchingApplication:andsceneFallbackDidFinishLaunchingApplication:are already idempotent, so calling them unconditionally is safe.UIApplication.connectedScenesand callengine:receivedConnectNotificationFor:for the first matching scene. This triggersscene:willConnectToSession:options:replay to the engine's plugins using the storedconnectionOptions.The storyboard path is unaffected:
awakeFromNibruns beforescene:willConnectToSession:fires, soconnectedScenesis empty when the new loop runs.Test
Updated
module_uiscene_test_ios.dartto point theFlutterImplicitEngineDelegate-AppMigrated-ImplicitFlutterEnginevariant atUITests-SceneEvents-ApplicationLaunchEvents.swift, which asserts thatapplicationWillFinishLaunchingWithOptions,applicationDidFinishLaunchingWithOptions,sceneWillConnect,sceneWillEnterForeground, andsceneDidBecomeActiveare all received — matching the storyboard variant's expectations.