Skip to content

[UIScene] Update AppLifecycleState for scenes #174400

@vashworth

Description

@vashworth

Problem

The Flutter widgets library provides the AppLifecycleListener so that applications can listen to changes in its state. These states are “resumed”, “inactive”, “hidden”, “paused”, and "detached".

  • Detached - The application is still hosted by a Flutter engine but is detached from any host views. When the application is in this state, the engine is running without a view.
  • Resumed - this corresponds to the app running in the foreground active state.
  • Inactive - At least one view of the application is visible, but none have input focus. The application is otherwise running normally. This state corresponds to the Flutter host view running in the foreground inactive state. Apps transition to this state when: in a phone call, responding to a TouchID request, entering the app switcher or the control center, or the UIViewController hosting the Flutter app is transitioning.
  • Hidden - All views of an application are hidden, either because the application is about to be paused
  • Paused - The application is not currently visible to the user, and not responding to user input.

Currently, Flutter uses lifecycle events/notifications from the FlutterAppDelegate and FlutterViewController to determine the state and send it to the framework.

Proposal 1 - AppLifecycleState is per FlutterViewController/FlutterEngine

If the AppLifecycleState is per FlutterViewController/FlutterEngine, it should be determined by view events and scene events.

For example, let’s say an app has 2 scenes, each with a FlutterEngine/FlutterViewController. Under this proposal, if Scene 1 is backgrounded, you’d expect the state of the FlutterEngine in Scene 1 to be “paused” and the state of the FlutterEngine in Scene 2 to be “resumed”. With our current setup, both would be “resumed”.

The following events would need to be replaced:

  • applicationBecameActive → sceneDidBecomeActive
  • applicationWillResignActive → sceneWillResignActive
  • applicationWillTerminate → sceneDidDisconnect
  • applicationDidEnterBackground → sceneDidEnterBackground
  • applicationWillEnterForeground → sceneWillEnterForeground

Pros:

  • Essentially AppLifecycleState would act more as if it was “EngineLifecycleState” or “SceneLifecycleState”
  • Less complex to implement

Cons:

  • Not inline with the future of multi-view (see “Multi-View Consideration” below).
  • May require changes in future if multi-view is adopted

Proposal 2 - AppLifecycleState is per Application

According to the documentation in app_lifecycle_state.h, these states should each be implemented with the whole application in mind rather than per-view. Each state should take into account multiple views in the following way:

  • Resumed: when any view is shown
  • Inactive: when all views are inactive
  • Hidden: when all views are hidden
  • Paused: not view specific
  • Detached: not view specific

Source: Flutter Multi-Window API (PUBLICLY SHARED)

To make this happen, we’d probably introduce an internal-only ViewLifecycleState. This would track the state of the FlutterViewController and would be saved to the FlutterEngine. Then when a lifecycle event occurs, we’d get the ViewLifecycleState for each FlutterViewController in each FlutterEngine to determine the AppLifecycleState.

To access other FlutterViewControllers and FlutterEngines, we can iterate through the Scenes and iterate through each FlutterEngine they have connected (see Proposal 1of “Plugin lifecycle events”).

Pros:

  • Inline with multi-view future
    Cons:
  • No way to track “SceneLifecycleState”

Metadata

Metadata

Labels

P2Important issues not at the top of the work listplatform-iosiOS applications specificallyteam-iosOwned by iOS platform teamtriaged-iosTriaged by iOS platform team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions