From 955106064028c247a0b47538c33233a64909103a Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 15 Nov 2021 15:34:19 +0100 Subject: [PATCH 1/6] [webview_flutter] Add onUrlChanged callback to platform interface --- .../CHANGELOG.md | 4 ++ .../webview_method_channel.dart | 3 ++ .../webview_platform_callbacks_handler.dart | 9 ++++- .../pubspec.yaml | 2 +- .../webview_method_channel_test.dart | 38 ++++++++++++++++++- .../ios/Runner.xcodeproj/project.pbxproj | 4 +- 6 files changed, 56 insertions(+), 4 deletions(-) diff --git a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md index 4c7434a86b41..212f1c4c4784 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.5.0 + +* Added `onUrlChanged` callback to platform callback handler. + ## 1.4.0 * Added `loadFile` and `loadHtml` interface methods. diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart index 8df9f4c62b33..3a6047d9d5d0 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/method_channel/webview_method_channel.dart @@ -53,6 +53,9 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { case 'onPageStarted': _platformCallbacksHandler.onPageStarted(call.arguments['url']!); return null; + case 'onUrlChanged': + _platformCallbacksHandler.onUrlChanged(call.arguments['url']!); + return null; case 'onWebResourceError': _platformCallbacksHandler.onWebResourceError( WebResourceError( diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_callbacks_handler.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_callbacks_handler.dart index 44dae2ece434..fd2df5fdde64 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_callbacks_handler.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_interface/webview_platform_callbacks_handler.dart @@ -24,9 +24,16 @@ abstract class WebViewPlatformCallbacksHandler { void onPageFinished(String url); /// Invoked by [WebViewPlatformController] when a page is loading. - /// /// Only works when [WebSettings.hasProgressTracking] is set to `true`. + /// Only works when [WebSettings.hasProgressTracking] is set to `true`. void onProgress(int progress); + /// Invoked by [WebViewPlatformController] when the webview's URL has changed. + /// + /// Unlike [onPageStarted], [onProgress], and [onPageFinished], + /// [onUrlChanged] also fires when navigating without a full page load + /// e.g. when using a single page application. + void onUrlChanged(String url); + /// Report web resource loading error to the host application. void onWebResourceError(WebResourceError error); } diff --git a/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml b/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml index 4a4746d8ab68..57ae9a06f056 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml @@ -4,7 +4,7 @@ repository: https://github.com/flutter/plugins/tree/master/packages/webview_flut issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview_flutter%22 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.4.0 +version: 1.5.0 environment: sdk: ">=2.12.0 <3.0.0" diff --git a/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart b/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart index 396013535aa9..f827d8fcf6b0 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/test/src/method_channel/webview_method_channel_test.dart @@ -13,7 +13,9 @@ import 'package:webview_flutter_platform_interface/webview_flutter_platform_inte void main() { TestWidgetsFlutterBinding.ensureInitialized(); - group('Tests on `plugin.flutter.io/webview_` channel', () { + group( + 'Tests on `plugin.flutter.io/webview_` channel dart->native', + () { const int channelId = 1; const MethodChannel channel = MethodChannel('plugins.flutter.io/webview_$channelId'); @@ -554,6 +556,40 @@ void main() { }); }); + group( + 'Tests on `plugin.flutter.io/webview_` channel native->dart', + () { + const int channelId = 1; + final WebViewPlatformCallbacksHandler callbacksHandler = + MockWebViewPlatformCallbacksHandler(); + final JavascriptChannelRegistry javascriptChannelRegistry = + MockJavascriptChannelRegistry(); + + MethodChannelWebViewPlatform( + channelId, + callbacksHandler, + javascriptChannelRegistry, + ); + + tearDown(() { + reset(callbacksHandler); + }); + + test('onUrlChanged', () async { + // Run + await ServicesBinding.instance!.defaultBinaryMessenger + .handlePlatformMessage( + 'plugins.flutter.io/webview_$channelId', + StandardMethodCodec() + .encodeMethodCall(MethodCall('onUrlChanged', {'url': 'Test Url'})), + null, + ); + + // Verify + verify(callbacksHandler.onUrlChanged('Test Url')); + }); + }); + group('Tests on `plugins.flutter.io/cookie_manager` channel', () { const MethodChannel cookieChannel = MethodChannel('plugins.flutter.io/cookie_manager'); diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj index ba0deb4781d4..362a1c24f07c 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj @@ -193,7 +193,6 @@ C370F140C3A19241FD8C5E64 /* Pods-RunnerTests.debug.xcconfig */, 5C776D27D0DDA247ED5EA72B /* Pods-RunnerTests.release.xcconfig */, ); - name = Pods; path = Pods; sourceTree = ""; }; @@ -282,6 +281,7 @@ }; 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; + DevelopmentTeam = 7624MWN53C; }; F7151F73266057800028CB91 = { CreatedOnToolsVersion = 12.5; @@ -616,6 +616,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 7624MWN53C; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -639,6 +640,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 7624MWN53C; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", From d6798c05f0deb08701c0674a62091adb1a69dab5 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 15 Nov 2021 15:42:17 +0100 Subject: [PATCH 2/6] [webview_flutter] Support new onUrlChanged event for iOS --- .../webview_flutter_wkwebview/CHANGELOG.md | 4 +++ .../FLTWKNavigationDelegateTests.m | 25 +++++++++++++++++++ .../example/lib/web_view.dart | 14 +++++++++++ .../ios/Classes/FLTWKNavigationDelegate.m | 13 ++++++++++ .../ios/Classes/FlutterWebView.m | 4 +++ .../webview_flutter_wkwebview/pubspec.yaml | 6 +++-- 6 files changed, 64 insertions(+), 2 deletions(-) diff --git a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md index 4db6dbfd2864..997d04bb58ce 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.3.0 + +* Support new `onUrlChanged` event in platform interface. + ## 2.2.0 * Implemented new `runJavascript` and `runJavascriptReturningResult` methods in platform interface. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FLTWKNavigationDelegateTests.m b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FLTWKNavigationDelegateTests.m index a819a9b53d60..16ea2667db38 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FLTWKNavigationDelegateTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FLTWKNavigationDelegateTests.m @@ -69,4 +69,29 @@ - (void)testWebViewWebEvaluateJavaScriptShouldNotBeCalledWhenShouldEnableZoomIsT [self.navigationDelegate webView:webview didFinishNavigation:navigation]; } +- (void)testWebViewObserveValueForKeyOPathCallsMethodChannelOnURLChange { + [self.navigationDelegate + observeValueForKeyPath:@"URL" + ofObject:nil + change:@{ + NSKeyValueChangeNewKey : [NSURL URLWithString:@"https://flutter.dev/"] + } + context:nil]; + OCMVerify([self.mockMethodChannel + invokeMethod:@"onUrlChanged" + arguments:[OCMArg isEqual:@{@"url" : @"https://flutter.dev/"}]]); +} + +- (void)testWebViewObserveValueForKeyOPathReturnsForNonURLChanges { + [self.navigationDelegate + observeValueForKeyPath:@"IRRELEVANT_PATH" + ofObject:nil + change:@{ + NSKeyValueChangeNewKey : [NSURL URLWithString:@"https://flutter.dev/"] + } + context:nil]; + + OCMReject([self.mockMethodChannel invokeMethod:[OCMArg any] arguments:[OCMArg any]]); +} + @end diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/lib/web_view.dart b/packages/webview_flutter/webview_flutter_wkwebview/example/lib/web_view.dart index 403db1f08ac6..3fe1a0a5623c 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/lib/web_view.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/lib/web_view.dart @@ -35,6 +35,9 @@ typedef void PageFinishedCallback(String url); /// Signature for when a [WebView] is loading a page. typedef void PageLoadingCallback(int progress); +/// Signature for when a [WebView] changed its current URL. +typedef void UrlChangedCallback(String url); + /// Signature for when a [WebView] has failed to load a resource. typedef void WebResourceErrorCallback(WebResourceError error); @@ -61,6 +64,7 @@ class WebView extends StatefulWidget { this.onPageStarted, this.onPageFinished, this.onProgress, + this.onUrlChanged, this.onWebResourceError, this.debuggingEnabled = false, this.gestureNavigationEnabled = false, @@ -175,6 +179,9 @@ class WebView extends StatefulWidget { /// Invoked when a page is loading. final PageLoadingCallback? onProgress; + /// Invoked when a webview's URL has changed. + final UrlChangedCallback? onUrlChanged; + /// Invoked when a web resource has failed to load. /// /// This callback is only called for the main page. @@ -611,6 +618,13 @@ class _PlatformCallbacksHandler implements WebViewPlatformCallbacksHandler { } } + @override + void onUrlChanged(String url) { + if (_webView.onUrlChanged != null) { + _webView.onUrlChanged!(url); + } + } + void onWebResourceError(WebResourceError error) { if (_webView.onWebResourceError != null) { _webView.onWebResourceError!(error); diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWKNavigationDelegate.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWKNavigationDelegate.m index 125d3cabdcf1..e0ed667db08a 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWKNavigationDelegate.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWKNavigationDelegate.m @@ -16,6 +16,19 @@ - (instancetype)initWithChannel:(FlutterMethodChannel *)channel { return self; } +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context { + if (![keyPath isEqualToString:@"URL"]) { + return; + } + NSURL *newURL = [change objectForKey:NSKeyValueChangeNewKey]; + if (newURL) { + [_methodChannel invokeMethod:@"onUrlChanged" arguments:@{@"url" : newURL.absoluteString}]; + } +} + #pragma mark - WKNavigationDelegate conformance - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m index 5e12f8acb2ea..9b9f18e036cd 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FlutterWebView.m @@ -109,6 +109,10 @@ - (instancetype)initWithFrame:(CGRect)frame _webView.scrollView.automaticallyAdjustsScrollIndicatorInsets = NO; } } + [_webView addObserver:_navigationDelegate + forKeyPath:@"URL" + options:NSKeyValueObservingOptionNew + context:NULL]; [self applySettings:settings]; // TODO(amirh): return an error if apply settings failed once it's possible to do so. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml index 5176adb9749c..bd4e859a252c 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter_wkwebview description: A Flutter plugin that provides a WebView widget based on Apple's WKWebView control. repository: https://github.com/flutter/plugins/tree/master/packages/webview_flutter/webview_flutter_wkwebview issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22 -version: 2.2.0 +version: 2.3.0 environment: sdk: ">=2.14.0 <3.0.0" @@ -18,7 +18,9 @@ flutter: dependencies: flutter: sdk: flutter - webview_flutter_platform_interface: ^1.2.0 + #TODO (BeMacized): CHANGE TO VERSION DEPENDENCY ONCE UPDATED PLATFORM INTERFACE HAS BEEN PUBLISHED. + webview_flutter_platform_interface: + path: ../webview_flutter_platform_interface dev_dependencies: flutter_driver: From 0fd9af27f7519b9033730a49f855d0a2e26dd2a4 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 15 Nov 2021 15:55:38 +0100 Subject: [PATCH 3/6] Fix merge --- .../webview_flutter/webview_flutter_wkwebview/pubspec.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml index 0dbfd7b3bda0..4ae2820522ce 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml @@ -18,13 +18,9 @@ flutter: dependencies: flutter: sdk: flutter -<<<<<<< HEAD #TODO (BeMacized): CHANGE TO VERSION DEPENDENCY ONCE UPDATED PLATFORM INTERFACE HAS BEEN PUBLISHED. webview_flutter_platform_interface: path: ../webview_flutter_platform_interface -======= - webview_flutter_platform_interface: ^1.3.0 ->>>>>>> url_notifications_platform dev_dependencies: flutter_driver: From 056e52ff2130a85a352702fb3dd25bca268fa28c Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Mon, 15 Nov 2021 16:36:16 +0100 Subject: [PATCH 4/6] Revert changes to project.pbxproj --- .../example/ios/Runner.xcodeproj/project.pbxproj | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj index f60d6c912f52..c83e0d82e4ec 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj @@ -193,6 +193,7 @@ C370F140C3A19241FD8C5E64 /* Pods-RunnerTests.debug.xcconfig */, 5C776D27D0DDA247ED5EA72B /* Pods-RunnerTests.release.xcconfig */, ); + name = Pods; path = Pods; sourceTree = ""; }; @@ -281,7 +282,6 @@ }; 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; - DevelopmentTeam = 7624MWN53C; }; F7151F73266057800028CB91 = { CreatedOnToolsVersion = 12.5; @@ -616,7 +616,6 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 7624MWN53C; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -640,7 +639,6 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 7624MWN53C; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", From 0bebda48d9469ef02e821b8df13bae9cfdde7a98 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Tue, 16 Nov 2021 10:08:50 +0100 Subject: [PATCH 5/6] Revert project.pbxproj change --- .../example/ios/Runner.xcodeproj/project.pbxproj | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj index c83e0d82e4ec..e292b1bd52fa 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj @@ -193,7 +193,6 @@ C370F140C3A19241FD8C5E64 /* Pods-RunnerTests.debug.xcconfig */, 5C776D27D0DDA247ED5EA72B /* Pods-RunnerTests.release.xcconfig */, ); - name = Pods; path = Pods; sourceTree = ""; }; From c0e12b81c43e7b04f04d8ea94d2a4db767271f25 Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Wed, 17 Nov 2021 14:34:17 +0100 Subject: [PATCH 6/6] Add missing test and fix null check --- .../ios/RunnerTests/FLTWKNavigationDelegateTests.m | 13 +++++++++++-- .../ios/Classes/FLTWKNavigationDelegate.m | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FLTWKNavigationDelegateTests.m b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FLTWKNavigationDelegateTests.m index 16ea2667db38..e35a1317d91a 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FLTWKNavigationDelegateTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FLTWKNavigationDelegateTests.m @@ -69,7 +69,7 @@ - (void)testWebViewWebEvaluateJavaScriptShouldNotBeCalledWhenShouldEnableZoomIsT [self.navigationDelegate webView:webview didFinishNavigation:navigation]; } -- (void)testWebViewObserveValueForKeyOPathCallsMethodChannelOnURLChange { +- (void)testWebViewObserveValueForKeyPathCallsMethodChannelOnURLChange { [self.navigationDelegate observeValueForKeyPath:@"URL" ofObject:nil @@ -82,7 +82,7 @@ - (void)testWebViewObserveValueForKeyOPathCallsMethodChannelOnURLChange { arguments:[OCMArg isEqual:@{@"url" : @"https://flutter.dev/"}]]); } -- (void)testWebViewObserveValueForKeyOPathReturnsForNonURLChanges { +- (void)testWebViewObserveValueForKeyPathReturnsForNonURLChanges { [self.navigationDelegate observeValueForKeyPath:@"IRRELEVANT_PATH" ofObject:nil @@ -94,4 +94,13 @@ - (void)testWebViewObserveValueForKeyOPathReturnsForNonURLChanges { OCMReject([self.mockMethodChannel invokeMethod:[OCMArg any] arguments:[OCMArg any]]); } +- (void)testWebViewObserveValueForKeyPathReturnsForNSNullURLChanges { + [self.navigationDelegate observeValueForKeyPath:@"URL" + ofObject:nil + change:@{NSKeyValueChangeNewKey : [NSNull null]} + context:nil]; + + OCMReject([self.mockMethodChannel invokeMethod:[OCMArg any] arguments:[OCMArg any]]); +} + @end diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWKNavigationDelegate.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWKNavigationDelegate.m index e0ed667db08a..c0233920d586 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWKNavigationDelegate.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWKNavigationDelegate.m @@ -24,7 +24,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath return; } NSURL *newURL = [change objectForKey:NSKeyValueChangeNewKey]; - if (newURL) { + if (![newURL isEqual:[NSNull null]]) { [_methodChannel invokeMethod:@"onUrlChanged" arguments:@{@"url" : newURL.absoluteString}]; } }