Skip to content

iOS web view plugin #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ build/
ios/.generated/
packages
pubspec.lock

example/ios/Podfile.lock
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
Plugin that allow Flutter to communicate with a native Webview.


***It will launch a new Activity inside the App with the Webview inside. Does not allow to integrate a Webview inside a Flutter Widget***
***For Android, it will launch a new Activity inside the App with the Webview inside. Does not allow to integrate a Webview inside a Flutter Widget***

TODO:
***For IOS, it will launch a new UIViewController inside the App with the UIWebView inside. Does not allow to integrate a Webview inside a Flutter Widget***

- [x] Android
- [ ] [IOS](https://github.com/dart-flitter/flutter_webview_plugin/issues/1)
- [x] IOS


## Getting Started
Expand All @@ -32,3 +32,7 @@ Add the Activity to you `AndroidManifest.xml`
<activity android:name="com.flutter_webview_plugin.WebviewActivity"
android:parentActivityName=".MainActivity"/>
```

### IOS

No extra configuration is needed
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.flutter.plugins;

import io.flutter.plugin.common.PluginRegistry;
import com.flutter_webview_plugin.FlutterWebviewPlugin;

/**
* Generated file. Do not edit.
*/
public final class GeneratedPluginRegistrant {
public static void registerWith(PluginRegistry registry) {
FlutterWebviewPlugin.registerWith(registry.registrarFor("com.flutter_webview_plugin.FlutterWebviewPlugin"));
}
}
3 changes: 0 additions & 3 deletions example/ios/Podfile.lock

This file was deleted.

22 changes: 11 additions & 11 deletions example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
objects = {

/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* PluginRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* PluginRegistry.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
945777F11EF64758001C8557 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 945777F01EF64758001C8557 /* GeneratedPluginRegistrant.m */; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
Expand All @@ -21,7 +21,7 @@
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
B1F3D14E8117A6C9F65810E0 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D558BB7489B1C82B42A9097 /* libPods-Runner.a */; };
C1AB67DD965258C508BF745D /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A3CDD044DB4E60255722586 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
Expand All @@ -40,14 +40,13 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* PluginRegistry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PluginRegistry.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* PluginRegistry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PluginRegistry.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
4D558BB7489B1C82B42A9097 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
945777EF1EF64758001C8557 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
945777F01EF64758001C8557 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9740EEB71CF902C7004384FC /* app.flx */ = {isa = PBXFileReference; lastKnownFileType = file; name = app.flx; path = Flutter/app.flx; sourceTree = "<group>"; };
Expand All @@ -58,6 +57,7 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9A3CDD044DB4E60255722586 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -67,7 +67,7 @@
files = (
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
B1F3D14E8117A6C9F65810E0 /* libPods-Runner.a in Frameworks */,
C1AB67DD965258C508BF745D /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -117,15 +117,15 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
945777EF1EF64758001C8557 /* GeneratedPluginRegistrant.h */,
945777F01EF64758001C8557 /* GeneratedPluginRegistrant.m */,
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* PluginRegistry.h */,
1498D2331E8E89220040F4C2 /* PluginRegistry.m */,
);
path = Runner;
sourceTree = "<group>";
Expand All @@ -141,7 +141,7 @@
CF3B75C9A7D2FA2A4C99F110 /* Frameworks */ = {
isa = PBXGroup;
children = (
4D558BB7489B1C82B42A9097 /* libPods-Runner.a */,
9A3CDD044DB4E60255722586 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
Expand Down Expand Up @@ -292,7 +292,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
Expand All @@ -304,7 +304,7 @@
files = (
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
97C146F31CF9000F007C117D /* main.m in Sources */,
1498D2341E8E89220040F4C2 /* PluginRegistry.m in Sources */,
945777F11EF64758001C8557 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
30 changes: 30 additions & 0 deletions example/ios/Runner.xcworkspace/xcshareddata/Runner.xcscmblueprint
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "089954AE9FE84C565F8189CE7B1E08C8949FC40C",
"DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {

},
"DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
"B9BC852104FA5F3F91D8B12EB80D37232CB3B40D" : 9223372036854775807,
"089954AE9FE84C565F8189CE7B1E08C8949FC40C" : 9223372036854775807
},
"DVTSourceControlWorkspaceBlueprintIdentifierKey" : "9839F02E-853D-4357-B537-73CD5272EC87",
"DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
"B9BC852104FA5F3F91D8B12EB80D37232CB3B40D" : "..\/..\/flutter",
"089954AE9FE84C565F8189CE7B1E08C8949FC40C" : "flutter_webview_plugin\/"
},
"DVTSourceControlWorkspaceBlueprintNameKey" : "Runner",
"DVTSourceControlWorkspaceBlueprintVersion" : 204,
"DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "example\/ios\/Runner.xcworkspace",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
{
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/dart-flitter\/flutter_webview_plugin.git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "089954AE9FE84C565F8189CE7B1E08C8949FC40C"
},
{
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/flutter\/flutter.git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "B9BC852104FA5F3F91D8B12EB80D37232CB3B40D"
}
]
}
11 changes: 5 additions & 6 deletions example/ios/Runner/AppDelegate.m
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
#include "AppDelegate.h"
#include "PluginRegistry.h"
#include "GeneratedPluginRegistrant.h"

@implementation AppDelegate {
PluginRegistry *plugins;
GeneratedPluginRegistrant *plugins;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
FlutterViewController *flutterController =
(FlutterViewController *)self.window.rootViewController;
plugins = [[PluginRegistry alloc] initWithController:flutterController];
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
return YES;
}

Expand Down
14 changes: 14 additions & 0 deletions example/ios/Runner/GeneratedPluginRegistrant.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// Generated file. Do not edit.
//

#ifndef GeneratedPluginRegistrant_h
#define GeneratedPluginRegistrant_h

#import <Flutter/Flutter.h>

@interface GeneratedPluginRegistrant : NSObject
+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry;
@end

#endif /* GeneratedPluginRegistrant_h */
14 changes: 14 additions & 0 deletions example/ios/Runner/GeneratedPluginRegistrant.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// Generated file. Do not edit.
//

#import "GeneratedPluginRegistrant.h"
#import <flutter_webview_plugin/FlutterWebviewPlugin.h>

@implementation GeneratedPluginRegistrant

+ (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
[FlutterWebviewPlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterWebviewPlugin"]];
}

@end
7 changes: 6 additions & 1 deletion ios/Classes/FlutterWebviewPlugin.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
#import <Flutter/Flutter.h>
#import "WebviewController.h"

static FlutterMethodChannel *channel;

@interface FlutterWebviewPlugin : NSObject<FlutterPlugin>
@end
@property (nonatomic, retain) UIViewController *viewController;
@property (nonatomic, retain) WebviewController *webviewController;
@end
50 changes: 42 additions & 8 deletions ios/Classes/FlutterWebviewPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,50 @@
static NSString *const CHANNEL_NAME = @"flutter_webview_plugin";

@implementation FlutterWebviewPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
channel = [FlutterMethodChannel
methodChannelWithName:CHANNEL_NAME
binaryMessenger:[registrar messenger]];
UIViewController *viewController = (UIViewController *)registrar.messenger;
FlutterWebviewPlugin* instance = [[FlutterWebviewPlugin alloc] initWithViewController:viewController];
[registrar addMethodCallDelegate:instance channel:channel];
}

- (instancetype)initWithViewController:(UIViewController *)viewController {
self = [super init];
if (self) {
self.viewController = viewController;
}
return self;
}

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
FlutterMethodChannel *channel =
[FlutterMethodChannel methodChannelWithName:CHANNEL_NAME binaryMessenger:registrar.messenger];
[channel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
NSString *method = [call method];
NSDictionary *arguments = [call arguments];
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if ([@"launch" isEqualToString:call.method]) {
[self showWebView:call];
result(nil);
} else if ([@"close" isEqualToString:call.method]) {
[self closeWebView];
result(nil);
} else {
result(FlutterMethodNotImplemented);
}
}

- (void)showWebView:(FlutterMethodCall*)call {
NSString *url = call.arguments[@"url"];
NSNumber *withJavascript = call.arguments[@"withJavascript"];
NSNumber *clearCache = call.arguments[@"clearCache"];
NSNumber *clearCookies = call.arguments[@"clearCookies"];
NSNumber *fullScreen = call.arguments[@"fullScreen"];

self.webviewController = [[WebviewController alloc] initWithUrl:url withJavascript:withJavascript clearCache:clearCache clearCookes:clearCookies fullScreen:fullScreen];

UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:self.webviewController];
[_viewController presentModalViewController:navigation animated:YES];
}

result(FlutterMethodNotImplemented);
}];
- (void)closeWebView {
[self.webviewController dismissViewControllerAnimated:YES completion:nil];
}

@end
13 changes: 13 additions & 0 deletions ios/Classes/WebviewController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// WebviewController.h
// Pods
//
// Created by Toufik Zitouni on 6/17/17.
//
//

#import <UIKit/UIKit.h>

@interface WebviewController : UIViewController
- (instancetype)initWithUrl:(NSString *)url withJavascript:(NSNumber *)withJavascript clearCache:(NSNumber *)clearCache clearCookes:(NSNumber *)clearCookies fullScreen:(NSNumber *)fullScreen;
@end
74 changes: 74 additions & 0 deletions ios/Classes/WebviewController.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// WebviewController.m
// Pods
//
// Created by Toufik Zitouni on 6/17/17.
//
//

#import "WebviewController.h"
#import "FlutterWebviewPlugin.h"

@interface WebviewController ()
@property (nonatomic, retain) NSString *url;
@property NSNumber *withJavascript;
@property NSNumber *clearCache;
@property NSNumber *clearCookies;
@property NSNumber *fullScreen;
@end

@implementation WebviewController

- (instancetype)initWithUrl:(NSString *)url withJavascript:(NSNumber *)withJavascript clearCache:(NSNumber *)clearCache clearCookes:(NSNumber *)clearCookies fullScreen:(NSNumber *)fullScreen {
self = [super init];
if (self) {
self.url = url;
self.withJavascript = withJavascript;
self.clearCache = clearCache;
self.clearCookies = clearCookies;
self.fullScreen = fullScreen;
}
return self;
}

- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(backButtonPressed:)];
self.navigationItem.leftBarButtonItem = backButton;

UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.frame];

if ([self.clearCache boolValue]) {
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}

if ([self.clearCookies boolValue]) {
[[NSURLSession sharedSession] resetWithCompletionHandler:^{

}];
}

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.url]]];

webView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self.view addSubview:webView];
}

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

if ([self.fullScreen boolValue]) {
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
}
}

- (IBAction)backButtonPressed:(id)sender {
[channel invokeMethod:@"onBackPressed" arguments:nil];
[self dismissViewControllerAnimated:YES completion:nil];
}

- (void)dealloc {
[channel invokeMethod:@"onDestroy" arguments:nil];
}

@end
Loading