diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/function_flutter_api_impls.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/function_flutter_api_impls.dart new file mode 100644 index 000000000000..c6eb711513d2 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/function_flutter_api_impls.dart @@ -0,0 +1,25 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'instance_manager.dart'; +import 'web_kit.pigeon.dart'; + +/// Flutter api to dispose functions. +class FunctionFlutterApiImpl extends FunctionFlutterApi { + /// Constructs a [FunctionFlutterApiImpl]. + FunctionFlutterApiImpl({InstanceManager? instanceManager}) { + this.instanceManager = instanceManager ?? InstanceManager.instance; + } + + /// Maintains instances stored to communicate with native language objects. + late final InstanceManager instanceManager; + + @override + void dispose(int instanceId) { + final Function? function = instanceManager.getInstance(instanceId); + if (function != null) { + instanceManager.removeInstance(function); + } + } +} diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.pigeon.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.pigeon.dart index 22013d2ff0cc..42f2ea344286 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.pigeon.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.pigeon.dart @@ -1017,6 +1017,75 @@ class WKNavigationDelegateHostApi { return; } } + + Future setDidFinishNavigation( + int arg_instanceId, int? arg_functionInstanceId) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WKNavigationDelegateHostApi.setDidFinishNavigation', + codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_instanceId, arg_functionInstanceId]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return; + } + } +} + +class _WKNavigationDelegateFlutterApiCodec extends StandardMessageCodec { + const _WKNavigationDelegateFlutterApiCodec(); +} + +abstract class WKNavigationDelegateFlutterApi { + static const MessageCodec codec = + _WKNavigationDelegateFlutterApiCodec(); + + void didFinishNavigation( + int functionInstanceId, int webViewInstanceId, String? url); + static void setup(WKNavigationDelegateFlutterApi? api, + {BinaryMessenger? binaryMessenger}) { + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFinishNavigation', + codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFinishNavigation was null.'); + final List args = (message as List?)!; + final int? arg_functionInstanceId = (args[0] as int?); + assert(arg_functionInstanceId != null, + 'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFinishNavigation was null, expected non-null int.'); + final int? arg_webViewInstanceId = (args[1] as int?); + assert(arg_webViewInstanceId != null, + 'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFinishNavigation was null, expected non-null int.'); + final String? arg_url = (args[2] as String?); + assert(arg_url != null, + 'Argument for dev.flutter.pigeon.WKNavigationDelegateFlutterApi.didFinishNavigation was null, expected non-null String.'); + api.didFinishNavigation( + arg_functionInstanceId!, arg_webViewInstanceId!, arg_url!); + return; + }); + } + } + } } class _NSObjectHostApiCodec extends StandardMessageCodec { @@ -1137,6 +1206,38 @@ class NSObjectHostApi { } } +class _FunctionFlutterApiCodec extends StandardMessageCodec { + const _FunctionFlutterApiCodec(); +} + +abstract class FunctionFlutterApi { + static const MessageCodec codec = _FunctionFlutterApiCodec(); + + void dispose(int instanceId); + static void setup(FunctionFlutterApi? api, + {BinaryMessenger? binaryMessenger}) { + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.FunctionFlutterApi.dispose', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.FunctionFlutterApi.dispose was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = (args[0] as int?); + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.FunctionFlutterApi.dispose was null, expected non-null int.'); + api.dispose(arg_instanceId!); + return; + }); + } + } + } +} + class _WKWebViewHostApiCodec extends StandardMessageCodec { const _WKWebViewHostApiCodec(); @override diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation.dart index 8aa315aa10ee..24dd55ac3ec8 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation.dart @@ -149,7 +149,11 @@ class NSObject { : _api = NSObjectHostApiImpl( binaryMessenger: binaryMessenger, instanceManager: instanceManager, - ); + ) { + // Ensures FlutterApis for the Foundation library and FunctionFlutterApi are + // set up. + FoundationFlutterApis.instance.ensureSetUp(); + } final NSObjectHostApiImpl _api; diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation_api_impls.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation_api_impls.dart index ec0d60cc748e..b007d1a8312c 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation_api_impls.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation_api_impls.dart @@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; +import '../common/function_flutter_api_impls.dart'; import '../common/instance_manager.dart'; import '../common/web_kit.pigeon.dart'; import 'foundation.dart'; @@ -35,6 +37,54 @@ Iterable }); } +/// Handles initialization of Flutter APIs for the Foundation library. +class FoundationFlutterApis { + /// Constructs a [FoundationFlutterApis]. + @visibleForTesting + FoundationFlutterApis({ + BinaryMessenger? binaryMessenger, + InstanceManager? instanceManager, + }) : _binaryMessenger = binaryMessenger { + functionFlutterApi = + FunctionFlutterApiImpl(instanceManager: instanceManager); + } + + static FoundationFlutterApis _instance = FoundationFlutterApis(); + + /// Sets the global instance containing the Flutter Apis for the Foundation library. + @visibleForTesting + static set instance(FoundationFlutterApis instance) { + _instance = instance; + } + + /// Global instance containing the Flutter Apis for the Foundation library. + static FoundationFlutterApis get instance { + return _instance; + } + + final BinaryMessenger? _binaryMessenger; + bool _hasBeenSetUp = false; + + /// Flutter Api for disposing functions. + /// + /// This FlutterApi is placed here because [FoundationFlutterApis.ensureSetUp] + /// is called inside [NSObject] and [NSObject] is the parent class of all + /// objects. + @visibleForTesting + late final FunctionFlutterApiImpl functionFlutterApi; + + /// Ensures all the Flutter APIs have been set up to receive calls from native code. + void ensureSetUp() { + if (!_hasBeenSetUp) { + FunctionFlutterApi.setup( + functionFlutterApi, + binaryMessenger: _binaryMessenger, + ); + _hasBeenSetUp = true; + } + } +} + /// Host api implementation for [NSObject]. class NSObjectHostApiImpl extends NSObjectHostApi { /// Constructs an [NSObjectHostApiImpl]. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit.dart index 0703ce1267d9..2775507a0427 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit.dart @@ -515,15 +515,20 @@ class WKUIDelegate { /// coordinate changes in your web view’s main frame. /// /// Wraps [WKNavigationDelegate](https://developer.apple.com/documentation/webkit/wknavigationdelegate?language=objc). -class WKNavigationDelegate { +class WKNavigationDelegate extends NSObject { /// Constructs a [WKNavigationDelegate]. WKNavigationDelegate({ BinaryMessenger? binaryMessenger, InstanceManager? instanceManager, - }) : _navigationDelegateApi = WKNavigationDelegateHostApiImpl( + }) : _navigationDelegateApi = WKNavigationDelegateHostApiImpl( + binaryMessenger: binaryMessenger, + instanceManager: instanceManager, + ), + super( binaryMessenger: binaryMessenger, instanceManager: instanceManager, ) { + WebKitFlutterApis.instance.ensureSetUp(); _navigationDelegateApi.createForInstances(this); } @@ -531,10 +536,7 @@ class WKNavigationDelegate { /// Called when navigation from the main frame has started. Future setDidStartProvisionalNavigation( - void Function( - WKWebView webView, - String? url, - )? + void Function(WKWebView webView, String? url)? didStartProvisionalNavigation, ) { throw UnimplementedError(); @@ -544,7 +546,10 @@ class WKNavigationDelegate { Future setDidFinishNavigation( void Function(WKWebView webView, String? url)? didFinishNavigation, ) { - throw UnimplementedError(); + return _navigationDelegateApi.setDidFinishNavigationFromInstance( + this, + didFinishNavigation, + ); } /// Called when permission is needed to navigate to new content. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit_api_impls.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit_api_impls.dart index 188f65cbe177..40b0f872d37b 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit_api_impls.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/web_kit/web_kit_api_impls.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import '../common/instance_manager.dart'; @@ -106,6 +107,51 @@ extension _NSUrlRequestConverter on NSUrlRequest { } } +/// Handles initialization of Flutter APIs for WebKit. +class WebKitFlutterApis { + /// Constructs a [WebKitFlutterApis]. + @visibleForTesting + WebKitFlutterApis({ + BinaryMessenger? binaryMessenger, + InstanceManager? instanceManager, + }) : _binaryMessenger = binaryMessenger { + navigationDelegateFlutterApi = WKNavigationDelegateFlutterApiImpl( + instanceManager: instanceManager, + ); + } + + static WebKitFlutterApis _instance = WebKitFlutterApis(); + + /// Sets the global instance containing the Flutter Apis for the WebKit library. + @visibleForTesting + static set instance(WebKitFlutterApis instance) { + _instance = instance; + } + + /// Global instance containing the Flutter Apis for the WebKit library. + static WebKitFlutterApis get instance { + return _instance; + } + + final BinaryMessenger? _binaryMessenger; + bool _hasBeenSetUp = false; + + /// Flutter Api for [WKNavigationDelegate]. + @visibleForTesting + late final WKNavigationDelegateFlutterApiImpl navigationDelegateFlutterApi; + + /// Ensures all the Flutter APIs have been set up to receive calls from native code. + void ensureSetUp() { + if (!_hasBeenSetUp) { + WKNavigationDelegateFlutterApi.setup( + navigationDelegateFlutterApi, + binaryMessenger: _binaryMessenger, + ); + _hasBeenSetUp = true; + } + } +} + /// Host api implementation for [WKWebSiteDataStore]. class WKWebsiteDataStoreHostApiImpl extends WKWebsiteDataStoreHostApi { /// Constructs a [WebsiteDataStoreHostApiImpl]. @@ -381,6 +427,47 @@ class WKNavigationDelegateHostApiImpl extends WKNavigationDelegateHostApi { await create(instanceId); } } + + /// Calls [setDidFinishNavigation] with the ids of the provided object instances. + Future setDidFinishNavigationFromInstance( + WKNavigationDelegate instance, + void Function(WKWebView, String?)? didFinishNavigation, + ) { + int? functionInstanceId; + if (didFinishNavigation != null) { + functionInstanceId = instanceManager.getInstanceId(didFinishNavigation) ?? + instanceManager.tryAddInstance(didFinishNavigation)!; + } + return setDidFinishNavigation( + instanceManager.getInstanceId(instance)!, + functionInstanceId, + ); + } +} + +/// Flutter api implementation for [WKNavigationDelegate]. +class WKNavigationDelegateFlutterApiImpl + extends WKNavigationDelegateFlutterApi { + /// Constructs a [WKNavigationDelegateFlutterApiImpl]. + WKNavigationDelegateFlutterApiImpl({InstanceManager? instanceManager}) { + this.instanceManager = instanceManager ?? InstanceManager.instance; + } + + /// Maintains instances stored to communicate with native language objects. + late final InstanceManager instanceManager; + + @override + void didFinishNavigation( + int functionInstanceId, + int webViewInstanceId, + String? url, + ) { + final void Function( + WKWebView webView, + String? url, + ) function = instanceManager.getInstance(functionInstanceId)!; + function(instanceManager.getInstance(webViewInstanceId)!, url); + } } /// Host api implementation for [WKWebView]. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart b/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart index 0d5328dda8d6..12a9237a9a97 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart @@ -281,6 +281,20 @@ abstract class WKScriptMessageHandlerHostApi { @HostApi(dartHostTestHandler: 'TestWKNavigationDelegateHostApi') abstract class WKNavigationDelegateHostApi { void create(int instanceId); + + void setDidFinishNavigation(int instanceId, int? functionInstanceId); +} + +/// Mirror of WKNavigationDelegate. +/// +/// See https://developer.apple.com/documentation/webkit/wknavigationdelegate?language=objc. +@FlutterApi() +abstract class WKNavigationDelegateFlutterApi { + void didFinishNavigation( + int functionInstanceId, + int webViewInstanceId, + String? url, + ); } /// Mirror of NSObject. @@ -300,6 +314,12 @@ abstract class NSObjectHostApi { void removeObserver(int instanceId, int observerInstanceId, String keyPath); } +/// Disposes references to functions. +@FlutterApi() +abstract class FunctionFlutterApi { + void dispose(int instanceId); +} + /// Mirror of WKWebView. /// /// See https://developer.apple.com/documentation/webkit/wkwebview?language=objc. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/function_flutter_api_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/function_flutter_api_test.dart new file mode 100644 index 000000000000..63e59386ceaf --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/function_flutter_api_test.dart @@ -0,0 +1,33 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:webview_flutter_wkwebview/src/common/instance_manager.dart'; +import 'package:webview_flutter_wkwebview/src/common/web_kit.pigeon.dart'; +import 'package:webview_flutter_wkwebview/src/foundation/foundation_api_impls.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + group('$FunctionFlutterApi', () { + late InstanceManager instanceManager; + + setUp(() { + instanceManager = InstanceManager(); + }); + + test('dispose', () { + final Function function = () {}; + final int functionInstanceId = instanceManager.tryAddInstance(function)!; + + FoundationFlutterApis.instance = FoundationFlutterApis( + instanceManager: instanceManager, + )..ensureSetUp(); + + FoundationFlutterApis.instance.functionFlutterApi + .dispose(functionInstanceId); + expect(instanceManager.getInstanceId(function), isNull); + }); + }); +} diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/test_web_kit.pigeon.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/test_web_kit.pigeon.dart index 78e4b9dcfd3d..e35f37eac826 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/test_web_kit.pigeon.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/test_web_kit.pigeon.dart @@ -707,6 +707,7 @@ abstract class TestWKNavigationDelegateHostApi { _TestWKNavigationDelegateHostApiCodec(); void create(int instanceId); + void setDidFinishNavigation(int instanceId, int? functionInstanceId); static void setup(TestWKNavigationDelegateHostApi? api, {BinaryMessenger? binaryMessenger}) { { @@ -728,6 +729,29 @@ abstract class TestWKNavigationDelegateHostApi { }); } } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WKNavigationDelegateHostApi.setDidFinishNavigation', + codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMockMessageHandler(null); + } else { + channel.setMockMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.WKNavigationDelegateHostApi.setDidFinishNavigation was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = (args[0] as int?); + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.WKNavigationDelegateHostApi.setDidFinishNavigation was null, expected non-null int.'); + final int? arg_functionInstanceId = (args[1] as int?); + assert(arg_functionInstanceId != null, + 'Argument for dev.flutter.pigeon.WKNavigationDelegateHostApi.setDidFinishNavigation was null, expected non-null int.'); + api.setDidFinishNavigation(arg_instanceId!, arg_functionInstanceId!); + return {}; + }); + } + } } } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.mocks.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.mocks.dart index 7bd208eeac05..b8552c5d8157 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.mocks.dart @@ -1,5 +1,5 @@ // Mocks generated by Mockito 5.1.0 from annotations -// in webview_flutter_wkwebview/example/ios/.symlinks/plugins/webview_flutter_wkwebview/test/src/foundation/foundation_test.dart. +// in webview_flutter_wkwebview/test/src/foundation/foundation_test.dart. // Do not manually edit this file. import 'package:mockito/mockito.dart' as _i1; diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.dart index d51fa9793dd4..f4714eb6d484 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; + import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; @@ -9,6 +11,7 @@ import 'package:webview_flutter_wkwebview/src/common/instance_manager.dart'; import 'package:webview_flutter_wkwebview/src/common/web_kit.pigeon.dart'; import 'package:webview_flutter_wkwebview/src/foundation/foundation.dart'; import 'package:webview_flutter_wkwebview/src/web_kit/web_kit.dart'; +import 'package:webview_flutter_wkwebview/src/web_kit/web_kit_api_impls.dart'; import '../common/test_web_kit.pigeon.dart'; import 'web_kit_test.mocks.dart'; @@ -28,9 +31,12 @@ void main() { group('WebKit', () { late InstanceManager instanceManager; + late WebKitFlutterApis flutterApis; setUp(() { instanceManager = InstanceManager(); + flutterApis = WebKitFlutterApis(instanceManager: instanceManager); + WebKitFlutterApis.instance = flutterApis; }); group('$WKWebsiteDataStore', () { @@ -319,12 +325,23 @@ void main() { group('$WKNavigationDelegate', () { late MockTestWKNavigationDelegateHostApi mockPlatformHostApi; + late WKWebView webView; + late WKNavigationDelegate navigationDelegate; setUp(() async { mockPlatformHostApi = MockTestWKNavigationDelegateHostApi(); TestWKNavigationDelegateHostApi.setup(mockPlatformHostApi); + TestWKWebViewConfigurationHostApi.setup( + MockTestWKWebViewConfigurationHostApi(), + ); + TestWKWebViewHostApi.setup(MockTestWKWebViewHostApi()); + webView = WKWebView( + WKWebViewConfiguration(instanceManager: instanceManager), + instanceManager: instanceManager, + ); + navigationDelegate = WKNavigationDelegate( instanceManager: instanceManager, ); @@ -332,6 +349,8 @@ void main() { tearDown(() { TestWKNavigationDelegateHostApi.setup(null); + TestWKWebViewConfigurationHostApi.setup(null); + TestWKWebViewHostApi.setup(null); }); test('create', () async { @@ -339,6 +358,31 @@ void main() { instanceManager.getInstanceId(navigationDelegate), )); }); + + test('setDidFinishNavigation', () async { + final Completer> argsCompleter = + Completer>(); + + navigationDelegate.setDidFinishNavigation( + (WKWebView webView, String? url) { + argsCompleter.complete([webView, url]); + }, + ); + + final int functionInstanceId = + verify(mockPlatformHostApi.setDidFinishNavigation( + instanceManager.getInstanceId(navigationDelegate), + captureAny, + )).captured.single as int; + + flutterApis.navigationDelegateFlutterApi.didFinishNavigation( + functionInstanceId, + instanceManager.getInstanceId(webView)!, + 'url', + ); + + expect(argsCompleter.future, completion([webView, 'url'])); + }); }); group('$WKWebView', () { diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.mocks.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.mocks.dart index a2f16317f1fe..621093d48373 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit/web_kit_test.mocks.dart @@ -33,6 +33,12 @@ class MockTestWKNavigationDelegateHostApi extends _i1.Mock void create(int? instanceId) => super.noSuchMethod(Invocation.method(#create, [instanceId]), returnValueForMissingStub: null); + @override + void setDidFinishNavigation(int? instanceId, int? functionInstanceId) => + super.noSuchMethod( + Invocation.method( + #setDidFinishNavigation, [instanceId, functionInstanceId]), + returnValueForMissingStub: null); } /// A class which mocks [TestWKPreferencesHostApi]. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit_webview_widget_test.mocks.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit_webview_widget_test.mocks.dart index 6c34e0c72004..00b20d5b4304 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit_webview_widget_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/web_kit_webview_widget_test.mocks.dart @@ -1,5 +1,5 @@ // Mocks generated by Mockito 5.1.0 from annotations -// in webview_flutter_wkwebview/example/ios/.symlinks/plugins/webview_flutter_wkwebview/test/src/web_kit_webview_widget_test.dart. +// in webview_flutter_wkwebview/test/src/web_kit_webview_widget_test.dart. // Do not manually edit this file. import 'dart:async' as _i5;