Repository navigation
[iOS]: Plugin Registration crash when adopting UISceneDelegate due to nil FlutterEngine #168228
Copy link
Copy link
Closed
Closed
Copy link
Labels
P1High-priority issues at the top of the work listHigh-priority issues at the top of the work listc: fatal crashCrashes that terminate the processCrashes that terminate the processplatform-iosiOS applications specificallyiOS applications specificallyteam-iosOwned by iOS platform teamOwned by iOS platform teamtriaged-iosTriaged by iOS platform teamTriaged by iOS platform team
Description
When following Apple's best practices of adopting UISceneDelegate, if the project uses any swift plugins, the project will crash at launch when plugins are registered because the objc bridge classes for swift FlutterPlugin subclasses will be nil.
I ran into this crash while trying to implement #167267, but I've also seen users in the wild running into this crash as well ( https://developer.apple.com/forums/thread/748671 ).
reproduction steps
flutter create -t plugin --platform=ios swiftplugincd swiftplugin- Add the following to
example/ios/Runner/Info.plist(Note that the value of the fields don't need to be valid because startup will crash before it is used).<key>UIApplicationSceneManifest</key> <dict> <key>UIApplicationSupportsMultipleScenes</key> <false/> <key>UISceneConfigurations</key> <dict> <key>UIWindowSceneSessionRoleApplication</key> <array> <dict> <key>UISceneClassName</key> <string>UIWindowScene</string> <key>UISceneDelegateClassName</key> <string>$(PRODUCT_MODULE_NAME).AppDelegate</string> <key>UISceneConfigurationName</key> <string>flutter</string> <key>UISceneStoryboardFile</key> <string>Main</string> </dict> </array> </dict> </dict>
cd example; flutter run
crash
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x0000000194f85b08 libswiftCore.dylib`swift_getObjectType + 36
frame #1: 0x000000010329935c plugintest`static PlugintestPlugin.register(registrar=__C.FlutterPluginRegistrar @ 0x000000016ce08b88) at PlugintestPlugin.swift:0
* frame #3: 0x000000010325d834 Runner.debug.dylib`+[GeneratedPluginRegistrant registerWithRegistry:](self=GeneratedPluginRegistrant, _cmd="registerWithRegistry:", registry=0x0000600000c0daa0) at GeneratedPluginRegistrant.m:25:3
frame #4: 0x000000010325d8c4 Runner.debug.dylib`AppDelegate.application(application=0x0000000103f05a80, launchOptions=nil) at AppDelegate.swift:10:31
frame #6: 0x0000000185b2e30c UIKitCore`-[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 312
frame #7: 0x0000000185b2f804 UIKitCore`-[UIApplication _callInitializationDelegatesWithActions:forCanvas:payload:fromOriginatingProcess:] + 2936
frame #8: 0x0000000185b34984 UIKitCore`-[UIApplication _runWithMainScene:transitionContext:completion:] + 976
frame #9: 0x00000001851405ec UIKitCore`-[_UISceneLifecycleMultiplexer completeApplicationLaunchWithFBSScene:transitionContext:] + 148
frame #10: 0x0000000185b316b0 UIKitCore`-[UIApplication _compellApplicationLaunchToCompleteUnconditionally] + 44
frame #11: 0x0000000185b319b8 UIKitCore`-[UIApplication _run] + 760
frame #12: 0x0000000185b35bd4 UIKitCore`UIApplicationMain + 124
frame #13: 0x0000000184f0a334 UIKitCore`UIKit.UIApplicationMain(Swift.Int32, Swift.Optional<Swift.UnsafeMutablePointer<Swift.UnsafeMutablePointer<Swift.Int8>>>, Swift.Optional<Swift.String>, Swift.Optional<Swift.String>) -> Swift.Int32 + 100
frame #16: 0x000000010325de10 Runner.debug.dylib`main at <compiler-generated>:0
frame #17: 0x0000000103009410 dyld_sim`start_sim + 20
frame #18: 0x00000001030d6b4c dyld`start + 6000
Inspecting the type in the debugger after the crash looks like this:
(lldb) po PlugintestPlugin.self
note: error: No module map file in /Users/aaclarke/Library/Developer/Xcode/DerivedData/Runner-akumchbkelcnzlcblbxzpccssdcp/Build/Products/Debug-iphonesimulator/Flutter.framework
error: Error [IRForTarget]: Couldn't resolve the class for an Objective-C static method call
doctor
[!] Flutter (Channel [user-branch], 3.32.0-1.0.pre.382, on macOS 15.4.1 24E263 darwin-arm64, locale en) [551ms]
! Flutter version 3.32.0-1.0.pre.382 on channel [user-branch] at /Users/aaclarke/dev/flutter
Currently on an unknown channel. Run `flutter channel` to switch to an official channel.
If that doesn't fix the issue, reinstall Flutter by following instructions at https://flutter.dev/setup.
! Upstream repository unknown source is not a standard remote.
Set environment variable "FLUTTER_GIT_URL" to unknown source to dismiss this error.
• Framework revision 448e3036e0 (28 minutes ago), 2025-05-02 09:38:10 -0700
• Engine revision 9ffc2d9ef3
• Dart version 3.9.0 (build 3.9.0-76.0.dev)
• DevTools version 2.46.0-dev.0
• If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.
[!] Android toolchain - develop for Android devices (Android SDK version 35.0.0-rc4) [1,093ms]
• Android SDK at /Users/aaclarke/Library/Android/sdk
• Emulator version 35.2.10.0 (build_id 12414864) (CL:N/A)
• Platform android-35, build-tools 35.0.0-rc4
• Java binary at: path/to/jdk/bin/java
This JDK is specified in your Flutter configuration.
To change the current JDK, run: `flutter config --jdk-dir="path/to/jdk"`.
✗ Cannot execute path/to/jdk/bin/java to determine the version
[!] Xcode - develop for iOS and macOS (Xcode 16.3) [1,107ms]
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 16E140
! CocoaPods 1.15.2 out of date (1.16.2 is recommended).
CocoaPods is a package manager for iOS or macOS platform code.
Without CocoaPods, plugins will not work on iOS or macOS.
For more info, see https://flutter.dev/to/platform-plugins
To update CocoaPods, see https://guides.cocoapods.org/using/getting-started.html#updating-cocoapods
[✓] Chrome - develop for the web [7ms]
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2024.2) [7ms]
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 21.0.3+-79915917-b509.11)
[✓] VS Code (version 1.99.3) [4ms]
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.110.0
[✓] Connected device (4 available) [6.3s]
• iPhone (5) (wireless) (mobile) • 00008110-001524D40A10401E • ios • iOS 18.4.1 22E252
• iPhone 16 Pro (mobile) • 9DA578E6-E85A-44FA-9673-D01C31F3B779 • ios • com.apple.CoreSimulator.SimRuntime.iOS-18-2 (simulator)
• macOS (desktop) • macos • darwin-arm64 • macOS 15.4.1 24E263 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 135.0.7049.116
[✓] Network resources [152ms]
• All expected network resources are available.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P1High-priority issues at the top of the work listHigh-priority issues at the top of the work listc: fatal crashCrashes that terminate the processCrashes that terminate the processplatform-iosiOS applications specificallyiOS applications specificallyteam-iosOwned by iOS platform teamOwned by iOS platform teamtriaged-iosTriaged by iOS platform teamTriaged by iOS platform team
Activity
gaaclarke commentedon May 2, 2025
@stuartmorgan-g is this a failure that we've run into in other circumstances with swift plugins where we are able to compile fine but at runtime the bridge classes are nil?
gaaclarke commentedon May 2, 2025
As an experiment I moved the
+[GeneratedPluginRegistrant registerWithRegistry:]call later in the app startup with a "dispatch after" and the crash still happened. The theory was maybe that was too early in app startup and the bridge wasn't initialized yet, but that doesn't seem to be the case.gaaclarke commentedon May 2, 2025
Jenn question if when it prints something like
is there a module map there? There is (albeit in a
Modulessubdirectory).gaaclarke commentedon May 2, 2025
Here is a similar crash where the user claimed it only happened in testflight: https://stackoverflow.com/questions/77206289/flutter-runs-locally-but-testflight-build-crashes-on-swift-getobjecttype
I tried adding the linker flags
-ObjCand-all_loadto the example target to see if the objc bridge code was being dropped by the linker, but that didn't fix it.gaaclarke commentedon May 2, 2025
I tried switching to swift package manager and it doesn't resolve the crash.
gaaclarke commentedon May 2, 2025
So in the reproduction above, the crash happens when attempting to use the
SwiftpluginPluginclass in theswiftpluginpackage.At the crash you can see the swiftplugin.framework is loaded:
I expect the symbols for the objc classes to exist in that binary, they do appear.
I am able to resolve the class with
NSClassFromString, however :That means we know the symbols is present in the binaries and it can be loaded, but for some reason
[SwiftpluginPlugin class]is not working. This makes it sound like the magic that appends the module name is not working. That may be the module map that is referenced in the error message?gaaclarke commentedon May 2, 2025
Editing the
GeneratedPluginRegistrantto doNSLog(@"%@", [SwiftpluginPlugin class]);works, it prints outswiftplugin.SwiftpluginPlugin, correctly mapping the name to module+name. This is weird because it didn't work when invoked from lldb. This also means my theory that we don't have the information to map from name to module+name is incorrect.gaaclarke commentedon May 2, 2025
Looking at the stacktrace again. It appears we are loading the register function fine. I got on a bit of a rabbit chase because
po [SwiftpluginPlugin class]didn't work in lldb.gaaclarke commentedon May 2, 2025
Okay, I think I've track down the root of the problem.
SwiftpluginPlugin.registeris called with a nilregistrar. I don't know for the life of me why all of the messages I got from lldb didn't clearly state that. The plist item is rearranging the startup somehow so that that was previously already initialized, now it isn't.hellohuanlin commentedon May 9, 2025
Sounds like this is the same problem as described in the design doc, and it's unrelated to Swift?
gaaclarke commentedon May 9, 2025
Yes, it turned to to be unrelated to swift. It just happened to show up in our swift tests because the objc tests would noop when it encountered a nil, swift gave us a crash in
swift_getObjectType.[-][iOS]: Swift plugins crash when adopting UISceneDelegate[/-][+][iOS]: Plugin Registration crash when adopting UISceneDelegate due to nil FlutterEngine[/+]damengzai commentedon Jun 4, 2025
try newest master branch 3.33.+,I have similar bug by flutter stable 3.32.1,but 3.33.+ is ok.
gaaclarke commentedon Jun 4, 2025
fixed in #169365
github-actions commentedon Jun 18, 2025
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.