-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[webview_flutter] Add loadAssetFile to load html file from local assets #1247
Changes from all commits
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 |
---|---|---|
|
@@ -48,7 +48,11 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { | |
|
||
if (params.containsKey("initialUrl")) { | ||
String url = (String) params.get("initialUrl"); | ||
webView.loadUrl(url); | ||
if (url.contains("://")) { | ||
webView.loadUrl(url); | ||
} else { | ||
webView.loadUrl("file:///android_asset/flutter_assets/" + url); | ||
} | ||
} | ||
} | ||
|
||
|
@@ -63,6 +67,9 @@ public void onMethodCall(MethodCall methodCall, Result result) { | |
case "loadUrl": | ||
loadUrl(methodCall, result); | ||
break; | ||
case "loadAssetFile": | ||
loadAssetFile(methodCall, result); | ||
break; | ||
case "updateSettings": | ||
updateSettings(methodCall, result); | ||
break; | ||
|
@@ -113,6 +120,12 @@ private void loadUrl(MethodCall methodCall, Result result) { | |
result.success(null); | ||
} | ||
|
||
private void loadAssetFile(MethodCall methodCall, Result result) { | ||
String url = (String) methodCall.arguments; | ||
webView.loadUrl("file:///android_asset/flutter_assets/" + url); | ||
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. Use |
||
result.success(null); | ||
} | ||
|
||
private void canGoBack(Result result) { | ||
result.success(webView.canGoBack()); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,13 +7,15 @@ | |
#import "JavaScriptChannelHandler.h" | ||
|
||
@implementation FLTWebViewFactory { | ||
NSObject<FlutterPluginRegistrar>* _registrar; | ||
NSObject<FlutterBinaryMessenger>* _messenger; | ||
} | ||
|
||
- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger { | ||
- (instancetype)initWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar { | ||
self = [super init]; | ||
if (self) { | ||
_messenger = messenger; | ||
_registrar = registrar; | ||
_messenger = registrar.messenger; | ||
} | ||
return self; | ||
} | ||
|
@@ -28,7 +30,7 @@ - (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger { | |
FLTWebViewController* webviewController = [[FLTWebViewController alloc] initWithFrame:frame | ||
viewIdentifier:viewId | ||
arguments:args | ||
binaryMessenger:_messenger]; | ||
registrar:_registrar]; | ||
return webviewController; | ||
} | ||
|
||
|
@@ -42,17 +44,20 @@ @implementation FLTWebViewController { | |
// The set of registered JavaScript channel names. | ||
NSMutableSet* _javaScriptChannelNames; | ||
FLTWKNavigationDelegate* _navigationDelegate; | ||
NSObject<FlutterPluginRegistrar>* _registrar; | ||
} | ||
|
||
- (instancetype)initWithFrame:(CGRect)frame | ||
viewIdentifier:(int64_t)viewId | ||
arguments:(id _Nullable)args | ||
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger { | ||
registrar:(NSObject<FlutterPluginRegistrar>*)registrar { | ||
if ([super init]) { | ||
_viewId = viewId; | ||
_registrar = registrar; | ||
|
||
NSString* channelName = [NSString stringWithFormat:@"plugins.flutter.io/webview_%lld", viewId]; | ||
_channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger]; | ||
_channel = [FlutterMethodChannel methodChannelWithName:channelName | ||
binaryMessenger:registrar.messenger]; | ||
_javaScriptChannelNames = [[NSMutableSet alloc] init]; | ||
|
||
WKUserContentController* userContentController = [[WKUserContentController alloc] init]; | ||
|
@@ -77,7 +82,11 @@ - (instancetype)initWithFrame:(CGRect)frame | |
|
||
NSString* initialUrl = args[@"initialUrl"]; | ||
if ([initialUrl isKindOfClass:[NSString class]]) { | ||
[self loadUrl:initialUrl]; | ||
if ([initialUrl rangeOfString:@"://"].location == NSNotFound) { | ||
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 here |
||
[self loadAssetFile:initialUrl]; | ||
} else { | ||
[self loadUrl:initialUrl]; | ||
} | ||
} | ||
} | ||
return self; | ||
|
@@ -92,6 +101,8 @@ - (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { | |
[self onUpdateSettings:call result:result]; | ||
} else if ([[call method] isEqualToString:@"loadUrl"]) { | ||
[self onLoadUrl:call result:result]; | ||
} else if ([[call method] isEqualToString:@"loadAssetFile"]) { | ||
[self onLoadAssetFile:call result:result]; | ||
} else if ([[call method] isEqualToString:@"canGoBack"]) { | ||
[self onCanGoBack:call result:result]; | ||
} else if ([[call method] isEqualToString:@"canGoForward"]) { | ||
|
@@ -133,6 +144,17 @@ - (void)onLoadUrl:(FlutterMethodCall*)call result:(FlutterResult)result { | |
} | ||
} | ||
|
||
- (void)onLoadAssetFile:(FlutterMethodCall*)call result:(FlutterResult)result { | ||
NSString* url = [call arguments]; | ||
if (![self loadAssetFile:url]) { | ||
result([FlutterError errorWithCode:@"loadAssetFile_failed" | ||
message:@"Failed parsing the URL" | ||
details:[NSString stringWithFormat:@"URL was: '%@'", url]]); | ||
} else { | ||
result(nil); | ||
} | ||
} | ||
|
||
- (void)onCanGoBack:(FlutterMethodCall*)call result:(FlutterResult)result { | ||
BOOL canGoBack = [_webView canGoBack]; | ||
result([NSNumber numberWithBool:canGoBack]); | ||
|
@@ -289,6 +311,20 @@ - (bool)loadUrl:(NSString*)url withHeaders:(NSDictionary<NSString*, NSString*>*) | |
return true; | ||
} | ||
|
||
- (bool)loadAssetFile:(NSString*)url { | ||
NSString* key = [_registrar lookupKeyForAsset:url]; | ||
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. It won't work if the url has search or hash parameters. 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.
Yes.. I try to load reactjs app from local file system. it is not loading url with bookmark (#). is there any work-around to load bookmark urls? 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. yes.. try to load bookmark url.. it is not working. . is there any work-around? 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.
The returned key of method 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. thanks for your response.. i'm new to objective c.. tried the proposed changes you described above.. still getting same error.. My changes are in from console log: 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. - (bool)loadAssetFile:(NSString*)url {
NSArray* array = [url componentsSeparatedByString:@"?"];
NSString* pathString = [array objectAtIndex:0];
NSLog(@"%@%@", @"pathString: ", pathString);
NSString* key = [_registrar lookupKeyForAsset:pathString];
NSURL* baseURL = [[NSBundle mainBundle] URLForResource:key withExtension:nil];
if (!baseURL) {
return false;
}
NSURL* newUrl = baseURL;
if ([array count] > 1) {
NSString* queryString = [array objectAtIndex:1];
NSLog(@"%@%@", @"queryString: ", queryString);
NSString* queryPart = [NSString stringWithFormat:@"%@%@", @"?", queryString];
NSLog(@"%@%@", @"queryPart: ", queryPart);
newUrl = [NSURL URLWithString:queryPart relativeToURL:baseURL];
}
if (@available(iOS 9.0, *)) {
[_webView loadFileURL:newUrl allowingReadAccessToURL:[NSURL URLWithString:@"file:///"]];
} else {
return false;
}
return true;
} |
||
NSURL* nsUrl = [[NSBundle mainBundle] URLForResource:key withExtension:nil]; | ||
if (!nsUrl) { | ||
return false; | ||
} | ||
if (@available(iOS 9.0, *)) { | ||
[_webView loadFileURL:nsUrl allowingReadAccessToURL:[NSURL URLWithString:@"file:///"]]; | ||
} else { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
- (void)registerJavaScriptChannels:(NSSet*)channelNames | ||
controller:(WKUserContentController*)userContentController { | ||
for (NSString* channelName in channelNames) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -429,6 +429,17 @@ class WebViewController { | |
}); | ||
} | ||
|
||
/// Loads the specified file. | ||
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. The docs should say that this is a Flutter asset. |
||
/// | ||
/// `url` must not be null. | ||
Future<void> loadAssetFile(String url) async { | ||
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: lets call it 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 isn't a url |
||
assert(url != null); | ||
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter. | ||
// https://github.com/flutter/flutter/issues/26431 | ||
// ignore: strong_mode_implicit_dynamic_method | ||
return _channel.invokeMethod('loadAssetFile', url); | ||
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. @shaqian could you update the PR to clear this comment? (add type parameter) 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. _channel undefined name |
||
} | ||
|
||
/// Accessor to the current URL that the WebView is displaying. | ||
/// | ||
/// If [WebView.initialUrl] was never specified, returns `null`. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes it so we accept something that isn't a URL as the
initialUrl
.We could consider adding an
initialAsset
parameter, but I'd leave it for a different PR as it warrants some more discussion (generally it seems like users tend to get confused by theinitialFoo
parameters)