Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[webview_flutter] Adds the loadFlutterAsset method to the interface. #4562

Conversation

mvanbeusekom
Copy link
Contributor

Adds the loadFlutterAsset method to the platform interface. This method, when implemented, is responsible for correctly loading HTML content that is part of the Flutter asset bundle.

flutter/flutter#27086

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [relevant style guides] and ran [the auto-formatter]. (Unlike the flutter/flutter repo, the flutter/plugins repo does use dart format.)
  • I signed the [CLA].
  • The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. [shared_preferences]
  • I listed at least one issue that this PR fixes in the description above.
  • I updated pubspec.yaml with an appropriate new version according to the [pub versioning philosophy], or this PR is [exempt from version changes].
  • I updated CHANGELOG.md to add a description of the change, [following repository CHANGELOG style].
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • All existing and new tests are passing.

Adds the `loadFlutterAsset` method to the platform interface. This
method, when implemented, is responsible for correctly loading HTML
content that  is part of the Flutter asset bundle.
@google-cla google-cla bot added the cla: yes label Dec 1, 2021
@mvanbeusekom mvanbeusekom changed the title Adds the loadFlutterAsset method to the interface. [webview_flutter] Adds the loadFlutterAsset method to the interface. Dec 1, 2021
@github-actions github-actions bot added the p: webview_flutter Edits files for a webview_flutter plugin label Dec 1, 2021
Copy link
Contributor

@stuartmorgan stuartmorgan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with one comment.

@override
Future<void> loadFlutterAsset(String key) async {
assert(key.isNotEmpty);
return _channel.invokeMethod<void>('loadFlutterAsset', key);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed this before with loadFile; for both of these methods, the docs claim that they throw ArgumentErrors in specific cases, but there's no mechanism for that here. Doesn't this method channel implementation need to have conversion logic that translates a specific error (e.g., by string matching on the error code) into an ArgumentError?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a good catch, I missed that completely.

Actually I need to look into this as I tested on Android where is maps to the Android WebView.loadUrl method which will simply load a 404 page not found page and doesn't throw any exception at all. If the behaviour on iOS is similar maybe it would be better to remove the documentation on throwing an ArgumentException.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On iOS we'd know that the resource lookup didn't return a path. Could we do that check on Android before passing the URL to the webview?

Changing the documentation would be okay, but I'd rather not have wildly different behavior on Android vs other platforms.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran some tests and on iOS an error is reported through the WebViewPlatformCallbacksHandler.onWebResourceError callback. On Android no error is reported and it just loads the default 404 page.

I guess for the loadFile which excepts a local path we can simply check the file system if the file exists using dart:io. For the loadFlutterAsset method this will be more difficult unless there is a way we can verify (on the Dart side) that the supplied asset exists. I am not sure there is a good solution otherwise.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unless there is a way we can verify (on the Dart side)

Why does it have to be on the Dart side? I meant querying the engine API to resolve a resource. We can expose that capability to the Dart code via method channel.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that on the Android the native side only exposes the loadUrl and loadData methods (as it matches the native WebView API). This means on the Android side we cannot distinguish between the Dart loadFile, loadFlutterAsset and loadUrl methods as they all call the loadUrl method.

How would we go about querying the engine API? I don't have any experience with that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, it looks like the engine always gives an answer on Android by constructing the path that it would be at, without actually checking that it's there. But I assume this would return null or [] for an asset that doesn't exist?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, I will try to confirm this tonight. If this works, would it then be appropriate to create a separate method channel call to expose this to Dart within the webview_flutter_android package?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that seems like the right approach given the structure of all the other calls in the current implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated the current implementation to correctly convert the PlatformException into a ArgumentError as mentioned in the documentation. Not sure if you want to give it another look since this change adds some additional code (including tests).

Converts the `PlatformException` into an `ArgumentException` when there
is a failure loading the file or asset.
Copy link
Contributor

@stuartmorgan stuartmorgan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with nits

try {
return await _channel.invokeMethod<void>('loadFlutterAsset', key);
} on PlatformException catch (ex) {
if (ex.code == 'loadFlutterAsset_failed') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we don't have to be compatible with an existing implementation (unlike loadFile) let's give this a specific code like loadFlutterAsset_invalidKey. If we ever have failure cases that aren't due to a bad key for some reason, we would't want them mapped to ArgumentError.

),
),
);
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add tests for both that errors with different codes aren't remapped to ArgumentErrors.

@mvanbeusekom mvanbeusekom added the waiting for tree to go green (Use "autosubmit") This PR is approved and tested, but waiting for the tree to be green to land. label Dec 2, 2021
@fluttergithubbot fluttergithubbot merged commit e5fc8b5 into flutter:master Dec 3, 2021
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Dec 3, 2021
@mvanbeusekom mvanbeusekom deleted the webview_platform_interface_load_assets branch December 3, 2021 07:45
amantoux pushed a commit to amantoux/plugins that referenced this pull request Dec 11, 2021
KyleFin pushed a commit to KyleFin/plugins that referenced this pull request Dec 21, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cla: yes p: webview_flutter Edits files for a webview_flutter plugin waiting for tree to go green (Use "autosubmit") This PR is approved and tested, but waiting for the tree to be green to land.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants