[Bug]: iOS connectivity_plus retains callbacks in multi-FlutterEngine apps
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 68/100
Research direction
Start in the iOS connectivity_plus implementation, focusing on ConnectivityPlusPlugin and PathMonitorConnectivityProvider and the engine registration lifecycle. Reproduce the multi-FlutterEngine create, subscribe, detach, and destroy cycle described in the issue. Done means each engine releases its event sink and connectivity monitor on teardown, callbacks no longer target detached engines, and other engines continue monitoring normally.
Written by the indexing model from the issue text.
Description
Platform
iOS, in applications that register connectivity_plus on more than one FlutterEngine (for example, a long-lived main engine plus short-lived secondary engines).
Plugin
connectivity_plus
Version
7.3.1
Flutter SDK
- Flutter 3.35.7 / Dart 3.9.2: production crash observed in our multi-engine host.
Steps to reproduce
- Create a long-lived FlutterEngine and register
connectivity_plus. - Create a second, short-lived FlutterEngine and register the plugin there too.
- Subscribe to
onConnectivityChangedon the secondary engine. - Destroy or detach the secondary engine while a network callback is pending, then repeat the create/destroy cycle.
Actual behavior
The iOS plugin retains callback chains after an engine is no longer usable:
ConnectivityPlusPlugin -> ConnectivityProvider -> connectivityUpdateHandler -> ConnectivityPlusPluginPathMonitorConnectivityProvider -> NWPathMonitor -> pathUpdateHandler -> PathMonitorConnectivityProvider
The callbacks are assigned as bound method references, which retain their owners. The plugin is also not published through the registrar, so Flutter cannot invoke detachFromEngine(for:) when the engine is deallocated.
In a multi-engine application this leaves stale providers and network callbacks associated with short-lived engines. A later callback can attempt to deliver an EventChannel event after that engine has exited, causing:
Sending a message before the FlutterEngine has been run.
The retained callback graph also prevents timely release of the plugin/provider.
Expected behavior
Each FlutterEngine should own an independent plugin lifecycle. When an engine is detached or deallocated, its connectivity monitor and EventChannel sink should be released without affecting other engines, and no callback should target the detached engine.
Proposed fix
- Use weak captures for both callback edges.
- Publish the plugin instance with
registrar.publish(instance). - Implement
detachFromEngine(for:)to clear the event sink and stop the engine-owned monitor.
This keeps normal connectivity monitoring unchanged while making teardown safe for multi-FlutterEngine hosts.
Code sample
final subscription =
Connectivity().onConnectivityChanged.listen((_) {});
// In a host application, dispose the secondary FlutterEngine while this
// subscription is active, then create another secondary engine.
Logs
Fatal Exception: NSInternalInconsistencyException
Sending a message before the FlutterEngine has been run.
-[FlutterEngine sendOnChannel:message:binaryReply:]
FlutterBinaryMessengerRelay
SetStreamHandlerMessageHandlerOnChannel
SwiftConnectivityPlusPlugin.connectivityUpdateHandler
- Dominant language
- Dart
- Stars
- 1.9k
- Forks
- 1.3k
- PR merge metrics
- No merged PRs in 30d
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from fluttercommunity/plus_plugins
-
bug triage
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
fluttercommunity/plus_plugins#3979 ·
-
bug triage
Difficulty 1/5 Under an hour Newbie friendliness 88/100
fluttercommunity/plus_plugins#3964 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
fluttercommunity/plus_plugins#3943 ·
-
enhancement triage
Difficulty 4/5 3-5 days Newbie friendliness 55/100
fluttercommunity/plus_plugins#3976 · 1 reaction ·
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
fluttercommunity/plus_plugins#3974 ·
All issues in fluttercommunity/plus_plugins
Similar issues
-
status: needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
a2ui-project/a2ui#2782 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
MaikuB/flutter_local_notifications#2832 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
flutter-webrtc/flutter-webrtc#2206 ·
-
from.page-issue
Difficulty 1/5 Under an hour Newbie friendliness 85/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
swciitg/onestop_flutter#563 ·