Repository navigation
Conversation
With the UIScene lifecycle, FlutterViewController destroys the engine on UISceneDidDisconnectNotification, before applicationWillTerminate: reaches plugins. A player that keeps rendering (e.g. background audio when the app is killed from the app switcher) then calls textureFrameAvailable on a null shell. Register as a scene delegate and clear the players in sceneDidDisconnect:, which Flutter forwards before the engine is torn down. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the remaining case of #181 for apps using the UIScene lifecycle.
FvpPluginwithaddSceneDelegate:when the Flutter SDK provides it.sceneDidDisconnect:, asapplicationWillTerminate:already does since fix crash when killing app on iOS #221.With UIScene,
FlutterViewControllercallsdestroyContextonUISceneDidDisconnectNotification, so the engine shell is reset beforeapplicationWillTerminate:reaches plugins. If a player is still rendering, typically with background audio when the app is killed from the app switcher,mdk.vdeccallstextureFrameAvailable:on a null shell.FlutterSceneDelegatenotifies scene delegates first, so the players are released while the engine is still alive. The registration is guarded by__has_include(<Flutter/FlutterSceneLifeCycle.h>),@available(iOS 13.0, *)andrespondsToSelector:; older Flutter SDKs and macOS are unchanged.The crash came back in my app when I adopted the UIScene lifecycle (
FlutterSceneDelegate, Flutter 3.41.9). From 16 September to 10 October 2026, Crashlytics recorded 1,827 fatal events affecting 1,279 users on iPhone and 601 events affecting 399 users on iPad, all onmdk.vdecright after the app moves to the background. An earlier release without scenes has no event for 13,363 users over 90 days.Reproduction
fvp-scene-disconnect-repro.zip contains a
flutter createproject (Flutter 3.41.9, fvp v0.39.0, MDK 0.39.0) with background audio andallowBackgroundPlayback: true, synthetic HLS media and a loop script. WithREPRO_DESTROY_SCENE=1, the app destroys its scene session 10 s after playback starts; SpringBoard handles it as "killed from app switcher". The iPhone simulator refusesrequestSceneSessionDestruction, so the steps use an iPad simulator.The script prints the exit status reported by launchd:
(2, 11, 11)is the SIGSEGV above,(0, 0, 0)a clean exit.README.mdhas the full steps and the Xcode 27 adjustments to the template.Testing
I haven't tested a real app-switcher kill on a physical device yet. Apps whose scene delegate doesn't forward to
FlutterSceneDelegate, and add-to-app hosts that dismiss theirFlutterViewController, still destroy the engine without notifying plugins; a null-shell check in-[FlutterEngine textureFrameAvailable:]would cover those in Flutter.