From 99ab576acc2ceccb66e0f4990efb45cbca4a6f97 Mon Sep 17 00:00:00 2001 From: sha Date: Thu, 21 Feb 2019 23:38:08 +0800 Subject: [PATCH 1/2] Add loadAssetFile to load html file from local assets --- .../webviewflutter/FlutterWebView.java | 14 +++++- .../ios/Classes/FlutterWebView.h | 4 +- .../ios/Classes/FlutterWebView.m | 46 ++++++++++++++++--- .../ios/Classes/WebViewFlutterPlugin.m | 2 +- .../webview_flutter/lib/webview_flutter.dart | 11 +++++ 5 files changed, 67 insertions(+), 10 deletions(-) diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 1ff869b04c61..74600fbbb798 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -35,7 +35,10 @@ 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); } } @@ -50,6 +53,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; @@ -94,6 +100,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); + result.success(null); + } + private void canGoBack(MethodCall methodCall, Result result) { result.success(webView.canGoBack()); } diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.h b/packages/webview_flutter/ios/Classes/FlutterWebView.h index 08e6b8ab53a8..e1aee1423fb4 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.h +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.h @@ -12,13 +12,13 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args - binaryMessenger:(NSObject*)messenger; + registar:(NSObject*)registrar; - (UIView*)view; @end @interface FLTWebViewFactory : NSObject -- (instancetype)initWithMessenger:(NSObject*)messenger; +- (instancetype)initWithRegistrar:(NSObject*)registrar; @end NS_ASSUME_NONNULL_END diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m index 87d4d25bd9dc..90d0e2142081 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m @@ -6,13 +6,15 @@ #import "JavaScriptChannelHandler.h" @implementation FLTWebViewFactory { + NSObject* _registrar; NSObject* _messenger; } -- (instancetype)initWithMessenger:(NSObject*)messenger { +- (instancetype)initWithRegistrar:(NSObject*)registrar { self = [super init]; if (self) { - _messenger = messenger; + _registrar = registrar; + _messenger = registrar.messenger; } return self; } @@ -27,7 +29,7 @@ - (instancetype)initWithMessenger:(NSObject*)messenger { FLTWebViewController* webviewController = [[FLTWebViewController alloc] initWithFrame:frame viewIdentifier:viewId arguments:args - binaryMessenger:_messenger]; + registar:_registrar]; return webviewController; } @@ -40,17 +42,19 @@ @implementation FLTWebViewController { NSString* _currentUrl; // The set of registered JavaScript channel names. NSMutableSet* _javaScriptChannelNames; + NSObject* _registrar; } - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args - binaryMessenger:(NSObject*)messenger { + registar:(NSObject*)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]; @@ -73,7 +77,10 @@ - (instancetype)initWithFrame:(CGRect)frame NSString* initialUrl = args[@"initialUrl"]; if ([initialUrl isKindOfClass:[NSString class]]) { - [self loadUrl:initialUrl]; + if ([initialUrl rangeOfString:@"://"].location == NSNotFound) + [self loadAssetFile:initialUrl]; + else + [self loadUrl:initialUrl]; } } return self; @@ -88,6 +95,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"]) { @@ -129,6 +138,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]); @@ -259,6 +279,20 @@ - (bool)loadUrl:(NSString*)url { return true; } +- (bool)loadAssetFile:(NSString*)url { + NSString* key = [_registrar lookupKeyForAsset:url]; + 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) { diff --git a/packages/webview_flutter/ios/Classes/WebViewFlutterPlugin.m b/packages/webview_flutter/ios/Classes/WebViewFlutterPlugin.m index cab9169df00a..542957e61992 100644 --- a/packages/webview_flutter/ios/Classes/WebViewFlutterPlugin.m +++ b/packages/webview_flutter/ios/Classes/WebViewFlutterPlugin.m @@ -6,7 +6,7 @@ @implementation FLTWebViewFlutterPlugin + (void)registerWithRegistrar:(NSObject*)registrar { FLTWebViewFactory* webviewFactory = - [[FLTWebViewFactory alloc] initWithMessenger:registrar.messenger]; + [[FLTWebViewFactory alloc] initWithRegistrar:registrar]; [registrar registerViewFactory:webviewFactory withId:@"plugins.flutter.io/webview"]; [FLTCookieManager registerWithRegistrar:registrar]; } diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index bcace13ca1be..84e88f9b4687 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -329,6 +329,17 @@ class WebViewController { return _channel.invokeMethod('loadUrl', url); } + /// Loads the specified file. + /// + /// `url` must not be null. + Future loadAssetFile(String url) async { + 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); + } + /// Accessor to the current URL that the WebView is displaying. /// /// If [WebView.initialUrl] was never specified, returns `null`. From 01b7104e2273420720ab27a12445109ec3e06d23 Mon Sep 17 00:00:00 2001 From: sha Date: Fri, 22 Feb 2019 08:09:49 +0800 Subject: [PATCH 2/2] Add loadAssetFile to load html file from local assets --- .../io/flutter/plugins/webviewflutter/FlutterWebView.java | 6 ++---- packages/webview_flutter/ios/Classes/FlutterWebView.m | 3 ++- packages/webview_flutter/ios/Classes/WebViewFlutterPlugin.m | 3 +-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 74600fbbb798..7e809ba303e7 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -35,10 +35,8 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { if (params.containsKey("initialUrl")) { String url = (String) params.get("initialUrl"); - if (url.contains("://")) - webView.loadUrl(url); - else - webView.loadUrl("file:///android_asset/flutter_assets/" + url); + if (url.contains("://")) webView.loadUrl(url); + else webView.loadUrl("file:///android_asset/flutter_assets/" + url); } } diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m index 90d0e2142081..e1021a31e29f 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m @@ -54,7 +54,8 @@ - (instancetype)initWithFrame:(CGRect)frame _registrar = registrar; NSString* channelName = [NSString stringWithFormat:@"plugins.flutter.io/webview_%lld", viewId]; - _channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:registrar.messenger]; + _channel = [FlutterMethodChannel methodChannelWithName:channelName + binaryMessenger:registrar.messenger]; _javaScriptChannelNames = [[NSMutableSet alloc] init]; WKUserContentController* userContentController = [[WKUserContentController alloc] init]; diff --git a/packages/webview_flutter/ios/Classes/WebViewFlutterPlugin.m b/packages/webview_flutter/ios/Classes/WebViewFlutterPlugin.m index 542957e61992..d2859a3d5d7c 100644 --- a/packages/webview_flutter/ios/Classes/WebViewFlutterPlugin.m +++ b/packages/webview_flutter/ios/Classes/WebViewFlutterPlugin.m @@ -5,8 +5,7 @@ @implementation FLTWebViewFlutterPlugin + (void)registerWithRegistrar:(NSObject*)registrar { - FLTWebViewFactory* webviewFactory = - [[FLTWebViewFactory alloc] initWithRegistrar:registrar]; + FLTWebViewFactory* webviewFactory = [[FLTWebViewFactory alloc] initWithRegistrar:registrar]; [registrar registerViewFactory:webviewFactory withId:@"plugins.flutter.io/webview"]; [FLTCookieManager registerWithRegistrar:registrar]; }