-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[webview_flutter_wkwebview] Implement WKNavigationDelegate.didFinishNavigation as a proof of concept for callback methods
#5199
Changes from 5 commits
8575387
cbffe3f
3537176
494fe56
370c418
5363b9a
009bb9d
9e3f951
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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,46 @@ Iterable<NSKeyValueObservingOptionsEnumData> | |
| }); | ||
| } | ||
|
|
||
| /// Handles initialization of Flutter APIs for the Foundation library. | ||
| class FoundationFlutterApis { | ||
| /// Constructs a [FoundationFlutterApis]. | ||
| /// | ||
| /// This should only be changed for testing purposes. | ||
| @visibleForTesting | ||
| FoundationFlutterApis({ | ||
| this.binaryMessenger, | ||
| InstanceManager? instanceManager, | ||
| }) { | ||
| functionFlutterApi = | ||
| FunctionFlutterApiImpl(instanceManager: instanceManager); | ||
| } | ||
|
|
||
| /// Mutable instance containing all Flutter Apis for the Foundation library. | ||
| /// | ||
| /// This should only be changed for testing purposes. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it be better to enforce this with a private variable, a public getter, and a |
||
| static FoundationFlutterApis instance = FoundationFlutterApis(); | ||
|
|
||
| /// Sends binary data across the Flutter platform barrier. | ||
| final BinaryMessenger? binaryMessenger; | ||
|
|
||
| bool _hasBeenSetUp = false; | ||
|
|
||
| /// Flutter Api for disposing functions. | ||
| @visibleForTesting | ||
| late final FunctionFlutterApiImpl functionFlutterApi; | ||
|
bparrishMines marked this conversation as resolved.
stuartmorgan-g marked this conversation as resolved.
|
||
|
|
||
| /// Ensures all the Flutter APIs have been setup to receive calls from native code. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: set up |
||
| void ensureSetUp() { | ||
| if (!_hasBeenSetUp) { | ||
| FunctionFlutterApi.setup( | ||
| functionFlutterApi, | ||
| binaryMessenger: binaryMessenger, | ||
| ); | ||
| _hasBeenSetUp = true; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Host api implementation for [NSObject]. | ||
| class NSObjectHostApiImpl extends NSObjectHostApi { | ||
| /// Constructs an [NSObjectHostApiImpl]. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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,44 @@ extension _NSUrlRequestConverter on NSUrlRequest { | |
| } | ||
| } | ||
|
|
||
| /// Handles initialization of Flutter APIs for WebKit. | ||
| class WebKitFlutterApis { | ||
| /// Constructs a [WebKitFlutterApis]. | ||
| /// | ||
| /// This should only be changed for testing purposes. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment doesn't make sense here, since the constructor doesn't change anything. |
||
| @visibleForTesting | ||
| WebKitFlutterApis({this.binaryMessenger, InstanceManager? instanceManager}) { | ||
| navigationDelegateFlutterApi = WKNavigationDelegateFlutterApiImpl( | ||
| instanceManager: instanceManager, | ||
| ); | ||
| } | ||
|
|
||
| /// Mutable instance containing all Flutter Apis for WebKit. | ||
| /// | ||
| /// This should only be changed for testing purposes. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same note here as in the other file; this can be a getter+annotated setter |
||
| static WebKitFlutterApis instance = WebKitFlutterApis(); | ||
|
|
||
| /// Sends binary data across the Flutter platform barrier. | ||
| final BinaryMessenger? binaryMessenger; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want this to be public? |
||
|
|
||
| bool _hasBeenSetUp = false; | ||
|
|
||
| /// Flutter Api for [WKNavigationDelegate]. | ||
| @visibleForTesting | ||
| late final WKNavigationDelegateFlutterApiImpl navigationDelegateFlutterApi; | ||
|
|
||
| /// Ensures all the Flutter APIs have been setup to receive calls from native code. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. set up |
||
| 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 +420,53 @@ class WKNavigationDelegateHostApiImpl extends WKNavigationDelegateHostApi { | |
| await create(instanceId); | ||
| } | ||
| } | ||
|
|
||
| /// Calls [setDidFinishNavigation] with the ids of the provided object instances. | ||
| Future<void> setDidFinishNavigationFromInstance( | ||
| WKNavigationDelegate instance, | ||
| void Function(WKWebView, String?)? didFinishNavigation, | ||
| ) { | ||
| int? functionInstanceId; | ||
| if (didFinishNavigation != null) { | ||
| functionInstanceId = instanceManager.getInstanceId(didFinishNavigation); | ||
| functionInstanceId ??= | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why |
||
| 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)! as void Function( | ||
| WKWebView webView, | ||
| String? url, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems worth typedefing this instead of repeating the signature twice.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I actually realized that |
||
| ); | ||
|
|
||
| function(instanceManager.getInstance(webViewInstanceId)!, url); | ||
| } | ||
| } | ||
|
|
||
| /// Host api implementation for [WKWebView]. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.