Use case
For multi scene support, the current setup is:
- FlutterSceneDelegate contains a FlutterPluginSceneLifeCycleDelegate:
|
@implementation FlutterSceneDelegate |
|
|
|
@synthesize sceneLifeCycleDelegate = _sceneLifeCycleDelegate; |
- FlutterPluginSceneLifeCycleDelegate contains a list of engines (to pipe lifecycle events to)
|
@interface FlutterPluginSceneLifeCycleDelegate () |
|
|
|
/** |
|
* An array of weak pointers to `FlutterEngine`s that have views within this scene. Flutter |
|
* automatically adds engines to this array. |
|
* |
|
* This array is lazily cleaned up. `updateFlutterManagedEnginesInScene:` should be called before |
|
* use to ensure it is up-to-date. |
|
*/ |
|
@property(nonatomic, strong) NSPointerArray* flutterManagedEngines; |
- Then engine changes scene association, we call these methods:
|
- (BOOL)registerSceneLifeCycleWithFlutterEngine:(FlutterEngine*)engine { |
|
- (BOOL)unregisterSceneLifeCycleWithFlutterEngine:(FlutterEngine*)engine { |
- Also in
FlutterView, we update scene association in willMoveToWindow:
|
- (void)willMoveToWindow:(UIWindow*)newWindow { |
|
// When a FlutterView moves windows, it may also be moving scenes. Add/remove the FlutterEngine |
|
// from the FlutterSceneLifeCycleProvider.sceneLifeCycleDelegate if it changes scenes. |
|
UIWindowScene* newScene = newWindow.windowScene; |
|
UIWindowScene* currentScene = self.window.windowScene; |
|
|
|
if (newScene == currentScene) { |
|
return; |
|
} |
|
|
|
// Remove the engine from the previous scene if it's no longer in that window and scene. |
|
FlutterPluginSceneLifeCycleDelegate* previousSceneLifeCycleDelegate = |
|
[FlutterPluginSceneLifeCycleDelegate fromScene:self.previousScene]; |
|
if (previousSceneLifeCycleDelegate) { |
|
[previousSceneLifeCycleDelegate removeFlutterManagedEngine:(FlutterEngine*)self.delegate]; |
|
self.previousScene = nil; |
|
} |
|
|
|
if (newScene) { |
|
// Add the engine to the new scene's lifecycle delegate. |
|
FlutterPluginSceneLifeCycleDelegate* newSceneLifeCycleDelegate = |
|
[FlutterPluginSceneLifeCycleDelegate fromScene:newScene]; |
|
if (newSceneLifeCycleDelegate) { |
|
[newSceneLifeCycleDelegate addFlutterManagedEngine:(FlutterEngine*)self.delegate]; |
|
} |
|
} else { |
|
// If the view is being removed from a window, store the current scene to remove the engine |
|
// from it later when the view is added to a new window. |
|
self.previousScene = currentScene; |
|
} |
|
} |
- Then when FlutterSceneDelegate receives lifecycle calls (e.g.
sceneDidEnterBackground), it forwards to all the plugins in all the associated engines.
Proposal
This setup conflated UIScene vs UISceneDelegate - When the engine moves from scene A to scene B, it's moving between UIScenes (rather than UISceneDelegates). Scene A and B may (or may not) share the same UISceneDelegate, which is just a delegate object to handle scene events.
Use case
For multi scene support, the current setup is:
flutter/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterSceneDelegate.mm
Lines 18 to 20 in 61fca76
flutter/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterSceneLifeCycle.mm
Lines 15 to 24 in 61fca76
flutter/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterSceneLifeCycle.mm
Line 53 in 61fca76
flutter/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterSceneLifeCycle.mm
Line 72 in 61fca76
FlutterView, we update scene association inwillMoveToWindow:flutter/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterView.mm
Lines 317 to 347 in a51da69
sceneDidEnterBackground), it forwards to all the plugins in all the associated engines.Proposal
This setup conflated
UIScenevsUISceneDelegate- When the engine moves from scene A to scene B, it's moving betweenUIScenes (rather thanUISceneDelegates). Scene A and B may (or may not) share the sameUISceneDelegate, which is just a delegate object to handle scene events.