packages icon indicating copy to clipboard operation
packages copied to clipboard

[webview_flutter_wkwebview] Extended Web View API on iOS to add flexibility when working with local HTML content

Open agavrilko opened this issue 8 months ago • 8 comments
trafficstars

Overview

The readAccessURLProvider property has been added to the WebKitWebViewControllerCreationParams class. This function allows customization of the path to associated resources when loading a local HTML page using loadFile on iOS.

What Is the Issue

[#136479] readAccessUrl of the webview_flutter_wkwebview should be accessible for customization

The native WKWebView takes two arguments when loading local HTML pages:

  1. The file URL – The local HTML file to be loaded.
  2. The read access URL – A file or directory that WKWebView can access (e.g., .css, .js files).

Currently, the Flutter implementation always sets the parent folder of the specified HTML file as the read access directory. This behavior is not configurable, which limits how local web content can be structured.

For example, the following structure does not work because the .css and .js files are not in the parent directory of the HTML file:

/app_resources/
│── styles/
│    ├── main.css
│
│── scripts/
│    ├── app.js
│
│── pages/
     ├── index.html  (Loaded file)

With the existing behavior, WKWebView cannot access styles/main.css and scripts/app.js because the parent folder of index.html (/pages/) does not contain them.

How This Resolves the Issue

The readAccessURLProvider property has been added to the WebKitWebViewControllerCreationParams class. This property accepts a function that takes the path of the HTML file being loaded and returns the path to the associated resources.

Screenshot at Mar 04 14-49-46

Each time loadFile is called, the controller invokes this function and passes its result as the second argument to the underlying WKWebView implementation.

By default, the function returns the parent directory of the specified HTML file, preserving the existing behavior when no custom provider is set.

Impact on End Users

  1. Developers can now explicitly specify the directory that WKWebView should allow access to when loading a local HTML page, providing greater flexibility in organizing assets.
  2. The existing API signature remains unchanged, ensuring that the update does not require any modifications to existing codebases unless the new functionality is utilized.

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

agavrilko avatar Mar 04 '25 23:03 agavrilko

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

google-cla[bot] avatar Mar 04 '25 23:03 google-cla[bot]

Hello @bparrishMines, Thank you for taking the time to review this MR! I would like to ensure that I understand your feedback before proceeding.

I initially aimed to introduce this minor update without making any API changes, focusing solely on exposing the functionality that was already present but not accessible to users. However, based on your comment, it seems you are suggesting a broader update that would introduce new APIs (e.g., LoadFileParams and a new/updated platform interface method).

Based on my understanding, your suggestion would require:

  1. Introducing LoadFileParams at the platform interface level.
  2. Extending the PlatformWebViewController to accept LoadFileParams instead of a plain string.
  3. Adapting webview_flutter_wkwebview with a WebKitLoadFileParams subclass.

webview_design_update

While this design would make the API more consistent and extensible, it would also introduce a breaking change for current users, requiring them to update their code. That is why I am in doubt.

And if my understanding is correct, should I just update an existing loadFile method or introduce a new one?

agavrilko avatar Apr 28 '25 23:04 agavrilko

@agavrilko I think you should create a new platform interface method named something like: PlatformWebViewController.loadFileWithParams(LoadFileParams). This is consistent with updates to other platform interfaces where we realized in hindsight the method should have taken a class so that we can add parameters later.

Everything else you stated seems correct.

Additionally, after this feature lands, PlatformWebViewController.loadFile can be deprecated and it can just call loadFileWithParams.

bparrishMines avatar Apr 29 '25 19:04 bparrishMines

Hello @bparrishMines

I'm seeing that the pipeline fails due to a version resolution issue:

Because webview_flutter_example depends on webview_flutter_platform_interface ^2.12.0 which doesn't match any versions, version solving failed.

Could you please advise on the proper workflow for updating versions across the packages? Also, when you have a moment, could you review the changes to ensure everything aligns with your expectations?

Thank you!

agavrilko avatar May 05 '25 18:05 agavrilko

@agavrilko Yes, you can follow https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changing-federated-plugins for the process.

bparrishMines avatar May 06 '25 19:05 bparrishMines

Hello @bparrishMines,

I need further assistance with this PR. I expected to see ...you can't publish a package that has dependency overrides..., as stated here.

But it looks like changing _platform_interface and implementations in the same PR is not allowed:

Changed packages: webview_flutter/webview_flutter,webview_flutter_android,webview_flutter_platform_interface,webview_flutter_wkwebview [0:00] Running for packages/webview_flutter/webview_flutter... Dart changes are not allowed to other packages in webview_flutter in the same PR as changes to public Dart code in webview_flutter_platform_interface, as this can cause accidental breaking changes to be missed by automated checks. Please split the changes to these two packages into separate PRs.

Should this change be split into 2 different PRs? If yes, please specify what parts should go to each.

agavrilko avatar May 29 '25 23:05 agavrilko

@agavrilko Is this waiting for another review? WebViewController.loadFileWithParams is still included in webview_flutter.

bparrishMines avatar Jun 23 '25 17:06 bparrishMines

@agavrilko Is this waiting for another review? WebViewController.loadFileWithParams is still included in webview_flutter.

Hello @bparrishMines, my apologies, I did not see the notification about your reply. The method was removed as requested.

I have rebased the branch onto the latest main and cleaned the rest of the code. Let me know what I should do next. Thank you for your assistance.

agavrilko avatar Jun 24 '25 22:06 agavrilko

Hello @bparrishMines, @stuartmorgan-g

Here is the PR with only platform interface changes. https://github.com/flutter/packages/pull/9697

Let me know if I applied the version bump correctly.

agavrilko avatar Jul 30 '25 00:07 agavrilko

Hello @bparrishMines, @stuartmorgan-g I updated PR after the platform interface was merged.

All tests and formatting passes just fine locally, However there is an issue on pipeline, which I am afraid I do not understand: image

error - lib/src/webkit_webview_controller.dart:44:41 - Classes can only extend other classes. Try specifying a different superclass, or removing the extends clause. - extends_non_class error - lib/src/webkit_webview_controller.dart:47:20 - No associated named super constructor parameter. Try changing the name to the name of an existing named super constructor parameter, or creating such named parameter. - super_formal_parameter_without_associated_named error - lib/src/webkit_webview_controller.dart:49:57 - The argument type 'dynamic' can't be assigned to the parameter type 'String'. - argument_type_not_assignable error - lib/src/webkit_webview_controller.dart:54:5 - Undefined class 'LoadFileParams'. Try changing the name to the name of an existing class, or creating a class with the name 'LoadFileParams'. - undefined_class error - lib/src/webkit_webview_controller.dart:448:5 - Undefined class 'LoadFileParams'. Try changing the name to the name of an existing class, or creating a class with the name 'LoadFileParams'. - undefined_class error - lib/src/webkit_webview_controller.dart:453:18 - The getter 'absoluteFilePath' isn't defined for the type 'WebKitLoadFileParams'. Try importing the library that defines 'absoluteFilePath', correcting the name to the name of an existing getter, or defining a getter or field named 'absoluteFilePath'. - undefined_getter error - test/webkit_webview_controller_test.dart:353:17 - The name 'LoadFileParams' isn't a class. Try correcting the name to match an existing class. - creation_with_non_type warning - lib/src/webkit_webview_controller.dart:447:16 - The method doesn't override an inherited method. Try updating this class to match the superclass, or removing the override annotation. - override_on_non_overriding_member warning - lib/src/webkit_webview_controller.dart:457:7 - Dead code. Try removing the code, or fixing the code before it so that it can be reached. - dead_code warning - lib/src/webkit_webview_controller.dart:458:9 - Dead code. Try removing the code, or fixing the code before it so that it can be reached. - dead_code info - lib/src/webkit_webview_controller.dart:447:16 - Missing documentation for a public member. Try adding documentation for the member. - public_member_api_docs

11 issues found.

Looks like the latest version is not being pulled:

webview_flutter_platform_interface 2.13.0 (2.14.0 available)

But why this happens I can't tell. Could you guide please?

agavrilko avatar Aug 04 '25 22:08 agavrilko

Looks like the latest version is not being pulled:

webview_flutter_platform_interface 2.13.0 (2.14.0 available)

But why this happens I can't tell. Could you guide please?

Because you have code that requires 2.14.0, but (incorrectly) haven't indicated in pubspec.yaml that the package requires 2.14.0, so the downgrade tests that validate that the minimum package versions are correctly expressing the requirements—to prevent clients from having exactly this same compilation failure—is failing.

stuartmorgan-g avatar Aug 05 '25 11:08 stuartmorgan-g

Thank you @stuartmorgan-g for explaining what downgrade tests are.

In this case, since main webview_backage depends on platform interface and depends on wkwebview & andorid, that depend on platform interface as well:

image

I believe it will be right to create another PR to update webview_flutter_android and webview_flutter_wkwebview. And then have just webview_flutter updated in this one.

Is my understanding correct?

agavrilko avatar Aug 05 '25 16:08 agavrilko

I believe it will be right to create another PR to update webview_flutter_android and webview_flutter_wkwebview. And then have just webview_flutter updated in this one.

I don't understand what you are proposing here, since there are no webview_flutter changes as part of this PR.

The solution to the CI failures is to update the packages in this PR to properly express the minimum versions of the dependencies they require.

stuartmorgan-g avatar Aug 05 '25 17:08 stuartmorgan-g

I have update the references in android and wkwebview packages.

agavrilko avatar Aug 05 '25 20:08 agavrilko