And add documentation that says it should not change because the delegate implementation is stateful. ## Pre-launch Checklist - [ ] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [ ] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [ ] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). 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. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
iOS Add-to-App UIScene Integration Test
This directory contains the assets and templates for an integration test that verifies the behavior of Flutter in an add-to-app scenario on iOS, specifically with regards to UIScene lifecycle events.
The test is located at dev/devicelab/bin/tasks/module_uiscene_test_ios.dart.
Purpose
This test ensures that Flutter behaves correctly when integrated into a native iOS application that uses UIScene for lifecycle management. It covers various scenarios, including:
- The native app has migrated to UIScene, but the Flutter plugin has not.
- Both the native app and the Flutter plugin have migrated to UIScene.
- The native app has not migrated to UIScene, but the Flutter plugin has.
- Neither the native app nor the Flutter plugin has migrated to UIScene.
The test checks whether the correct lifecycle events (e.g., scene-based or application-based) are sent to the Flutter plugin in each scenario.
Directory Structure
xcode_uikit_swift: A template for a native iOS app using UIKit and Swift. This app acts as the host for the Flutter module.native: Contains Swift files used to replace files in thexcode_uikit_swifttemplate for different test scenarios. This includes different implementations ofAppDelegate.swift,SceneDelegate.swift,ViewController.swift, and the UI tests that verify the lifecycle events.flutterapp: Contains themain.dartandpubspec.yamlfiles for the Flutter module (my_module) used in the test.flutterplugin: Contains the files for the Flutter plugin (my_plugin) used in the test, including different implementations for migrated and unmigrated lifecycle event handling.
Dart template files don't have a .dart extension so the analyzer will ignore them. They don't work on their own outside of the module, app, or plugin they're copied into.
How to run the test
This test is intended to be run as a Flutter devicelab test. To run it locally, you can use the following command from the flutter/dev/devicelab directory:
../../bin/cache/dart-sdk/bin/dart bin/test_runner.dart test -t module_uiscene_test_ios
You can also run it with a local engine build:
../../bin/cache/dart-sdk/bin/dart bin/test_runner.dart test -t module_uiscene_test_ios --local-engine <your_local_engine> --local-engine-host host_debug
The test create the Flutter module, Flutter plugin, and native iOS app and deletes them at the end of the test. You can also create these files in a specific directory that will not be deleted:
../../bin/cache/dart-sdk/bin/dart bin/test_runner.dart test -t module_uiscene_test_ios --task-args destination=[/path/to/copy/destination]
Adding a new scenario
To add a new test scenario, you need to modify the scenarios map in the Scenarios class in dev/devicelab/bin/tasks/module_uiscene_test_ios.dart.
Each scenario is defined by a list of FileReplacements that swap out files in the generated Xcode project with templates from this directory.
To add a new scenario:
- Add a new entry to the
scenariosmap. The key is the name of your new scenario. - The value is a
List<FileReplacements>. EachFileReplacementsobject takes a source template file and a destination path in the generated project. - If your scenario requires new file content, add the new template files to the appropriate subdirectory (
native,flutterapp, orflutterplugin). - Reference these new template files in the
FileReplacementsfor your new scenario.