| #import "FlutterWebView.h" |
| |
| @implementation FLTWebViewFactory { |
| NSObject<FlutterBinaryMessenger>* _messenger; |
| } |
| |
| - (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger { |
| self = [super init]; |
| if (self) { |
| _messenger = messenger; |
| } |
| return self; |
| } |
| |
| - (NSObject<FlutterMessageCodec>*)createArgsCodec { |
| return [FlutterStandardMessageCodec sharedInstance]; |
| } |
| |
| - (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame |
| viewIdentifier:(int64_t)viewId |
| arguments:(id _Nullable)args { |
| FLTWebViewController* webviewController = [[FLTWebViewController alloc] initWithFrame:frame |
| viewIdentifier:viewId |
| arguments:args |
| binaryMessenger:_messenger]; |
| return webviewController; |
| } |
| |
| @end |
| |
| @implementation FLTWebViewController { |
| WKWebView* _webView; |
| int64_t _viewId; |
| FlutterMethodChannel* _channel; |
| } |
| |
| - (instancetype)initWithFrame:(CGRect)frame |
| viewIdentifier:(int64_t)viewId |
| arguments:(id _Nullable)args |
| binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger { |
| if ([super init]) { |
| _viewId = viewId; |
| _webView = [[WKWebView alloc] initWithFrame:frame]; |
| NSString* channelName = [NSString stringWithFormat:@"plugins.flutter.io/webview_%lld", viewId]; |
| _channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger]; |
| __weak __typeof__(self) weakSelf = self; |
| [_channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { |
| [weakSelf onMethodCall:call result:result]; |
| }]; |
| NSDictionary<NSString*, id>* settings = args[@"settings"]; |
| [self applySettings:settings]; |
| NSString* initialUrl = args[@"initialUrl"]; |
| if (initialUrl && initialUrl != [NSNull null]) { |
| [self loadUrl:initialUrl]; |
| } |
| } |
| return self; |
| } |
| |
| - (UIView*)view { |
| return _webView; |
| } |
| |
| - (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { |
| if ([[call method] isEqualToString:@"updateSettings"]) { |
| [self onUpdateSettings:call result:result]; |
| } else if ([[call method] isEqualToString:@"loadUrl"]) { |
| [self onLoadUrl:call result:result]; |
| } else if ([[call method] isEqualToString:@"canGoBack"]) { |
| [self onCanGoBack:call result:result]; |
| } else if ([[call method] isEqualToString:@"canGoForward"]) { |
| [self onCanGoForward:call result:result]; |
| } else if ([[call method] isEqualToString:@"goBack"]) { |
| [self onGoBack:call result:result]; |
| } else if ([[call method] isEqualToString:@"goForward"]) { |
| [self onGoForward:call result:result]; |
| } else { |
| result(FlutterMethodNotImplemented); |
| } |
| } |
| |
| - (void)onUpdateSettings:(FlutterMethodCall*)call result:(FlutterResult)result { |
| [self applySettings:[call arguments]]; |
| result(nil); |
| } |
| |
| - (void)onLoadUrl:(FlutterMethodCall*)call result:(FlutterResult)result { |
| NSString* url = [call arguments]; |
| if (![self loadUrl:url]) { |
| result([FlutterError errorWithCode:@"loadUrl_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]); |
| } |
| |
| - (void)onCanGoForward:(FlutterMethodCall*)call result:(FlutterResult)result { |
| BOOL canGoForward = [_webView canGoForward]; |
| result([NSNumber numberWithBool:canGoForward]); |
| } |
| |
| - (void)onGoBack:(FlutterMethodCall*)call result:(FlutterResult)result { |
| [_webView goBack]; |
| result(nil); |
| } |
| |
| - (void)onGoForward:(FlutterMethodCall*)call result:(FlutterResult)result { |
| [_webView goForward]; |
| result(nil); |
| } |
| |
| - (void)applySettings:(NSDictionary<NSString*, id>*)settings { |
| for (NSString* key in settings) { |
| if ([key isEqualToString:@"jsMode"]) { |
| NSNumber* mode = settings[key]; |
| [self updateJsMode:mode]; |
| } else { |
| NSLog(@"webview_flutter: unknown setting key: %@", key); |
| } |
| } |
| } |
| |
| - (void)updateJsMode:(NSNumber*)mode { |
| WKPreferences* preferences = [[_webView configuration] preferences]; |
| switch ([mode integerValue]) { |
| case 0: // disabled |
| [preferences setJavaScriptEnabled:NO]; |
| break; |
| case 1: // unrestricted |
| [preferences setJavaScriptEnabled:YES]; |
| break; |
| default: |
| NSLog(@"webview_flutter: unknown javascript mode: %@", mode); |
| } |
| } |
| |
| - (bool)loadUrl:(NSString*)url { |
| NSURL* nsUrl = [NSURL URLWithString:url]; |
| if (!nsUrl) { |
| return false; |
| } |
| NSURLRequest* req = [NSURLRequest requestWithURL:nsUrl]; |
| [_webView loadRequest:req]; |
| return true; |
| } |
| |
| @end |