From ec8a69bd9ca42aa80ea9aaef98b10045c38bca5f Mon Sep 17 00:00:00 2001 From: Maurice Parrish <10687576+bparrishMines@users.noreply.github.com> Date: Wed, 15 Jun 2022 11:33:14 -0700 Subject: [PATCH] [webview_flutter_wkwebview] Prevents `NSObject.removeObserver` from being called without calling `addObserver` first (#5975) --- .../lib/src/web_kit_webview_widget.dart | 12 ++++++++---- .../test/src/web_kit_webview_widget_test.dart | 10 ++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) 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', () {