diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit_webview_widget.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit_webview_widget.dart index a5c7c8f86ab6..99195fba4c33 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit_webview_widget.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit_webview_widget.dart @@ -93,6 +93,7 @@ class WebKitWebViewPlatformController extends WebViewPlatformController { bool _zoomEnabled = true; bool _hasNavigationDelegate = false; + bool _progressObserverSet = false; final Map _scriptMessageHandlers = {}; @@ -455,17 +456,20 @@ class WebKitWebViewPlatformController extends WebViewPlatformController { await _resetUserScripts(removedJavaScriptChannels: javascriptChannelNames); } - Future _setHasProgressTracking(bool hasProgressTracking) { + Future _setHasProgressTracking(bool hasProgressTracking) async { if (hasProgressTracking) { - return webView.addObserver( + _progressObserverSet = true; + await webView.addObserver( webView, keyPath: 'estimatedProgress', options: { NSKeyValueObservingOptions.newValue, }, ); - } else { - return webView.removeObserver(webView, keyPath: 'estimatedProgress'); + } else if (_progressObserverSet) { + // Calls to removeObserver before addObserver causes a crash. + _progressObserverSet = false; + await webView.removeObserver(webView, keyPath: 'estimatedProgress'); } } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit_webview_widget_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit_webview_widget_test.dart index a1656badad01..3580afe1c3a2 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit_webview_widget_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit_webview_widget_test.dart @@ -1195,6 +1195,16 @@ void main() { verify(mockCallbacksHandler.onProgress(32)); }); + + testWidgets('progress observer is not removed without being set first', + (WidgetTester tester) async { + await buildWidget(tester, hasProgressTracking: false); + + verifyNever(mockWebView.removeObserver( + mockWebView, + keyPath: 'estimatedProgress', + )); + }); }); group('JavascriptChannelRegistry', () {