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

Commit c070f30

Browse files
authored
Initial iOS implementation for webview_flutter. (#890)
1 parent 8388ee6 commit c070f30

File tree

7 files changed

+168
-24
lines changed

7 files changed

+168
-24
lines changed

packages/webview_flutter/example/ios/Runner/Info.plist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
<string>UIInterfaceOrientationLandscapeLeft</string>
4040
<string>UIInterfaceOrientationLandscapeRight</string>
4141
</array>
42+
<key>io.flutter.embedded_views_preview</key>
43+
<true/>
4244
<key>UIViewControllerBasedStatusBarAppearance</key>
4345
<false/>
4446
</dict>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#import <Flutter/Flutter.h>
2+
#import <WebKit/WebKit.h>
3+
4+
NS_ASSUME_NONNULL_BEGIN
5+
6+
@interface FLTWebViewController : NSObject<FlutterPlatformView>
7+
8+
- (instancetype)initWithWithFrame:(CGRect)frame
9+
viewIdentifier:(int64_t)viewId
10+
arguments:(id _Nullable)args
11+
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
12+
13+
- (UIView*)view;
14+
@end
15+
16+
@interface FLTWebViewFactory : NSObject<FlutterPlatformViewFactory>
17+
- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
18+
@end
19+
20+
NS_ASSUME_NONNULL_END
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#import "FlutterWebView.h"
2+
3+
@implementation FLTWebViewFactory {
4+
NSObject<FlutterBinaryMessenger>* _messenger;
5+
}
6+
7+
- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
8+
self = [super init];
9+
if (self) {
10+
_messenger = messenger;
11+
}
12+
return self;
13+
}
14+
15+
- (NSObject<FlutterMessageCodec>*)createArgsCodec {
16+
return [FlutterStandardMessageCodec sharedInstance];
17+
}
18+
19+
- (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
20+
viewIdentifier:(int64_t)viewId
21+
arguments:(id _Nullable)args {
22+
FLTWebViewController* webviewController =
23+
[[FLTWebViewController alloc] initWithWithFrame:frame
24+
viewIdentifier:viewId
25+
arguments:args
26+
binaryMessenger:_messenger];
27+
return webviewController;
28+
}
29+
30+
@end
31+
32+
@implementation FLTWebViewController {
33+
WKWebView* _webView;
34+
int64_t _viewId;
35+
FlutterMethodChannel* _channel;
36+
}
37+
38+
- (instancetype)initWithWithFrame:(CGRect)frame
39+
viewIdentifier:(int64_t)viewId
40+
arguments:(id _Nullable)args
41+
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
42+
if ([super init]) {
43+
_viewId = viewId;
44+
_webView = [[WKWebView alloc] initWithFrame:frame];
45+
NSString* channelName = [NSString stringWithFormat:@"plugins.flutter.io/webview_%lld", viewId];
46+
_channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger];
47+
__weak __typeof__(self) weakSelf = self;
48+
[_channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
49+
[weakSelf onMethodCall:call result:result];
50+
}];
51+
NSDictionary<NSString*, id>* settings = args[@"settings"];
52+
[self applySettings:settings];
53+
NSString* initialUrl = args[@"initialUrl"];
54+
if (initialUrl) {
55+
[self loadUrl:initialUrl];
56+
}
57+
}
58+
return self;
59+
}
60+
61+
- (UIView*)view {
62+
return _webView;
63+
}
64+
65+
- (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
66+
if ([[call method] isEqualToString:@"updateSettings"]) {
67+
[self onUpdateSettings:call result:result];
68+
} else if ([[call method] isEqualToString:@"loadUrl"]) {
69+
[self onLoadUrl:call result:result];
70+
} else {
71+
result(FlutterMethodNotImplemented);
72+
}
73+
}
74+
75+
- (void)onUpdateSettings:(FlutterMethodCall*)call result:(FlutterResult)result {
76+
[self applySettings:[call arguments]];
77+
result(nil);
78+
}
79+
80+
- (void)onLoadUrl:(FlutterMethodCall*)call result:(FlutterResult)result {
81+
NSString* url = [call arguments];
82+
if (![self loadUrl:url]) {
83+
result([FlutterError errorWithCode:@"loadUrl_failed"
84+
message:@"Failed parsing the URL"
85+
details:[NSString stringWithFormat:@"URL was: '%@'", url]]);
86+
} else {
87+
result(nil);
88+
}
89+
}
90+
91+
- (void)applySettings:(NSDictionary<NSString*, id>*)settings {
92+
for (NSString* key in settings) {
93+
if ([key isEqualToString:@"jsMode"]) {
94+
NSNumber* mode = settings[key];
95+
[self updateJsMode:mode];
96+
} else {
97+
NSLog(@"webview_flutter: unknown setting key: %@", key);
98+
}
99+
}
100+
}
101+
102+
- (void)updateJsMode:(NSNumber*)mode {
103+
WKPreferences* preferences = [[_webView configuration] preferences];
104+
switch ([mode integerValue]) {
105+
case 0: // disabled
106+
[preferences setJavaScriptEnabled:NO];
107+
break;
108+
case 1: // unrestricted
109+
[preferences setJavaScriptEnabled:YES];
110+
break;
111+
default:
112+
NSLog(@"webview_flutter: unknown javascript mode: %@", mode);
113+
}
114+
}
115+
116+
- (bool)loadUrl:(NSString*)url {
117+
NSURL* nsUrl = [NSURL URLWithString:url];
118+
if (!nsUrl) {
119+
return false;
120+
}
121+
NSURLRequest* req = [NSURLRequest requestWithURL:nsUrl];
122+
[_webView loadRequest:req];
123+
return true;
124+
}
125+
126+
@end
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#import "WebViewFlutterPlugin.h"
2+
#import "FlutterWebView.h"
3+
4+
@implementation FLTWebviewFlutterPlugin
5+
6+
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
7+
FLTWebViewFactory* webviewFactory =
8+
[[FLTWebViewFactory alloc] initWithMessenger:registrar.messenger];
9+
[registrar registerViewFactory:webviewFactory withId:@"plugins.flutter.io/webview"];
10+
}
11+
12+
@end

packages/webview_flutter/ios/Classes/WebviewFlutterPlugin.m

Lines changed: 0 additions & 24 deletions
This file was deleted.

packages/webview_flutter/lib/webview_flutter.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ class _WebViewState extends State<WebView> {
8888
creationParamsCodec: const StandardMessageCodec(),
8989
),
9090
);
91+
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
92+
return UiKitView(
93+
viewType: 'plugins.flutter.io/webview',
94+
onPlatformViewCreated: _onPlatformViewCreated,
95+
gestureRecognizers: widget.gestureRecognizers,
96+
creationParams: _CreationParams.fromWidget(widget).toMap(),
97+
creationParamsCodec: const StandardMessageCodec(),
98+
);
9199
}
92100
return Text(
93101
'$defaultTargetPlatform is not yet supported by the webview_flutter plugin');

0 commit comments

Comments
 (0)