diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 5564f63f..7df95f0c 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -16,7 +16,19 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -36,8 +48,8 @@
-
-
+
+
@@ -45,13 +57,31 @@
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -68,20 +98,6 @@
- assert(
- sNotEmpty()
- loadData
- _valide
- initialized
- HashMap
- headers
- .cast
- WebView
- print
- throw
- InAppWeb
- Boolean
- [WebHistory.list]
open
Cannot laod
_throwIsNotOpened
@@ -98,6 +114,20 @@
initialData
openData
optionsType
+ InAppWebView
+ fromInAppBrowser
+ InAppWebViewController
+ _handleMethod
+ InAppBrowser
+ handlerTest
+ onLoadStart
+ distributionUrl
+ args.putIfAbsent('isData', () => false);
+ VERSIONING_SYSTEM
+ config.build_settings['SWIFT_VERSION']
+ BUILD TARGET
+ InAppWebView {
+ AndroidView
activity.getPreferences(0)
@@ -132,26 +162,29 @@
-
+
+
+
+
+
+
+
+
-
-
-
-
-
+
-
-
+
+
@@ -159,7 +192,35 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -178,29 +239,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -368,33 +406,33 @@
-
+
+
-
+
-
+
-
-
+
+
-
@@ -418,55 +456,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -510,23 +499,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -534,20 +506,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -572,13 +530,6 @@
-
-
-
-
-
-
-
@@ -643,54 +594,178 @@
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 922ca138..bcd59553 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+## 0.6.0
+
+- added support for **iOS** inline native WebView integrated in the flutter widget tree
+- updated example folder (thanks to [marquesinijatinha](https://github.com/marquesinijatinha))
+- Fixed bug where passing null to expiresDate failed (thanks to [Sense545](https://github.com/Sense545))
+- Fixed iOS error: encode resourceURL (thanks to [igtm](https://github.com/igtm))
+- Fixed iOS error: Double value cannot be converted to Int because the result would be greater than Int.max in 32-bit devices (thanks to [huzhiren](https://github.com/huzhiren))
+- Fixed iOS error: problem in ChromeSafariBrowser (thanks to [marquesinijatinha](https://github.com/marquesinijatinha))
+- Fixed Android build error caused by gradle and build gradle versions (thanks to [tje3d](https://github.com/tje3d))
+
## 0.5.51
- updated `pubspec.yaml`
diff --git a/README.md b/README.md
index a4927014..953b6808 100644
--- a/README.md
+++ b/README.md
@@ -15,12 +15,30 @@ This plugin is inspired by the popular [cordova-plugin-inappbrowser](https://git
- Flutter: ">=0.10.1 <2.0.0"
### IMPORTANT Note for iOS
-To be able to use this plugin on iOS, you need to create the Flutter App with `flutter create -i swift` (see [flutter/flutter#13422 (comment)](https://github.com/flutter/flutter/issues/13422#issuecomment-392133780)), otherwise, you will get this message:
+If you are starting a new fresh app, you need to create the Flutter App with `flutter create -i swift` (see [flutter/flutter#13422 (comment)](https://github.com/flutter/flutter/issues/13422#issuecomment-392133780)), otherwise, you will get this message:
```
=== BUILD TARGET flutter_inappbrowser OF PROJECT Pods WITH CONFIGURATION Debug ===
The “Swift Language Version” (SWIFT_VERSION) build setting must be set to a supported value for targets which use Swift. Supported values are: 3.0, 4.0, 4.2. This setting can be set in the build settings editor.
```
-that is not true! The Swift version that I have used is already a supported value: 4.0.
+
+If you still have this problem, try to edit iOS `Podfile` like this (see [#15](https://github.com/pichillilorenzo/flutter_inappbrowser/issues/15)):
+```
+target 'Runner' do
+ use_frameworks! # required by simple_permission
+ ...
+end
+
+post_install do |installer|
+ installer.pods_project.targets.each do |target|
+ target.build_configurations.each do |config|
+ config.build_settings['SWIFT_VERSION'] = '4.0' # required by simple_permission
+ config.build_settings['ENABLE_BITCODE'] = 'NO'
+ end
+ end
+end
+```
+
+Instead, if you have already a non-swift project, you can check this issue to solve the problem: [Friction adding swift plugin to objective-c project](https://github.com/flutter/flutter/issues/16049).
## Getting Started
@@ -34,7 +52,7 @@ First, add `flutter_inappbrowser` as a [dependency in your pubspec.yaml file](ht
## Usage
Classes:
-- [InAppWebView](#inappwebview-class): Flutter Widget for adding an **inline native WebView** integrated in the flutter widget tree. [**Available only for Android** ([AndroidView](https://docs.flutter.io/flutter/widgets/AndroidView-class.html)) at this moment. For iOS, it will be available as soon as the Flutter team will release the corresponding dart class.].
+- [InAppWebView](#inappwebview-class): Flutter Widget for adding an **inline native WebView** integrated in the flutter widget tree. To use `InAppWebView` class on iOS you need to opt-in for the embedded views preview by adding a boolean property to the app's `Info.plist` file, with the key `io.flutter.embedded_views_preview` and the value `YES`.
- [InAppBrowser](#inappbrowser-class): In-App Browser using native WebView.
- [ChromeSafariBrowser](#chromesafaribrowser-class): In-App Browser using [Chrome Custom Tabs](https://developer.android.com/reference/android/support/customtabs/package-summary) on Android / [SFSafariViewController](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller) on iOS.
- [InAppLocalhostServer](#inapplocalhostserver-class): This class allows you to create a simple server on `http://localhost:[port]/`. The default `port` value is `8080`.
@@ -45,11 +63,10 @@ See the online [docs](https://pub.dartlang.org/documentation/flutter_inappbrowse
### `InAppWebView` class
Flutter Widget for adding an **inline native WebView** integrated in the flutter widget tree.
-[AndroidView](https://docs.flutter.io/flutter/widgets/AndroidView-class.html) is not officially stable yet!
+[AndroidView](https://docs.flutter.io/flutter/widgets/AndroidView-class.html) and [UiKitView](https://docs.flutter.io/flutter/widgets/UiKitView-class.html) is not officially stable yet!
So, if you want use it, you can but you will have some limitation such as the inability to use the keyboard!
-**Available only for Android** ([AndroidView](https://docs.flutter.io/flutter/widgets/AndroidView-class.html)) at this moment.
-For iOS, it will be available as soon as the Flutter team will release the corresponding dart class.
+To use `InAppWebView` class on iOS you need to opt-in for the embedded views preview by adding a boolean property to the app's `Info.plist` file, with the key `io.flutter.embedded_views_preview` and the value `YES`.
Use `InAppWebViewController` to control the WebView instance.
Example:
@@ -189,6 +206,10 @@ Screenshots:
![android](https://user-images.githubusercontent.com/5956938/47271038-7aebda80-d574-11e8-98fd-41e6bbc9fe2d.gif)
+- iOS:
+
+![ios](https://user-images.githubusercontent.com/5956938/54096363-e1e72000-43ab-11e9-85c2-983a830ab7a0.gif)
+
#### InAppWebView.initialUrl
Initial url that will be loaded.
diff --git a/android/build.gradle b/android/build.gradle
index 29bac20f..26af5d43 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -8,7 +8,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.1.2'
+ classpath 'com.android.tools.build:gradle:3.3.0'
}
}
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
index 9a4163a4..d76b502e 100644
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebViewClient.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebViewClient.java
index 35da3b6d..e8386107 100644
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebViewClient.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppWebView/InAppWebViewClient.java
@@ -359,14 +359,15 @@ public class InAppWebViewClient extends WebViewClient {
getChannel().invokeMethod("onLoadResource", obj);
- return new WebResourceResponse(
- response.header("content-type", "text/plain").split(";")[0].trim(),
- response.header("content-encoding"),
- response.code(),
- reasonPhrase,
- headersResponse,
- dataStream
- );
+ // this return is not working (it blocks some resources), so return null
+// return new WebResourceResponse(
+// response.header("content-type", "text/plain").split(";")[0].trim(),
+// response.header("content-encoding", "utf-8"),
+// response.code(),
+// reasonPhrase,
+// headersResponse,
+// dataStream
+// );
} catch (IOException e) {
e.printStackTrace();
Log.d(LOG_TAG, e.getMessage());
diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties
index 7ea28b9f..0ea206f2 100644
--- a/example/android/gradle/wrapper/gradle-wrapper.properties
+++ b/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj
index 04493bf3..3e370621 100644
--- a/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/example/ios/Runner.xcodeproj/project.pbxproj
@@ -446,7 +446,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_SWIFT3_OBJC_INFERENCE = On;
+ SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
VERSIONING_SYSTEM = "apple-generic";
};
@@ -474,7 +474,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.pichillilorenzo.flutter_inappbrowserExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
- SWIFT_SWIFT3_OBJC_INFERENCE = On;
+ SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
VERSIONING_SYSTEM = "apple-generic";
};
diff --git a/example/lib/webview_example.screen.dart b/example/lib/webview_example.screen.dart
index 407d5475..b27ea888 100644
--- a/example/lib/webview_example.screen.dart
+++ b/example/lib/webview_example.screen.dart
@@ -4,7 +4,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_inappbrowser/flutter_inappbrowser.dart';
class MyInappBrowser extends InAppBrowser {
- @override
+
+ @override
Future onBrowserCreated() async {
print("\n\nBrowser Ready!\n\n");
}
@@ -64,7 +65,7 @@ class MyInappBrowser extends InAppBrowser {
}
class WebviewExampleScreen extends StatefulWidget {
- final InAppBrowser browser = new InAppBrowser();
+ final InAppBrowser browser = new MyInappBrowser();
@override
_WebviewExampleScreenState createState() => new _WebviewExampleScreenState();
}
diff --git a/flutter_inappbrowser.iml b/flutter_inappbrowser.iml
index 4b6ef47a..456cf06e 100644
--- a/flutter_inappbrowser.iml
+++ b/flutter_inappbrowser.iml
@@ -20,7 +20,7 @@
-
+
diff --git a/ios/Classes/InAppBrowserWebViewController.swift b/ios/Classes/InAppBrowserWebViewController.swift
index 52edc1a2..f8f43ab6 100644
--- a/ios/Classes/InAppBrowserWebViewController.swift
+++ b/ios/Classes/InAppBrowserWebViewController.swift
@@ -14,73 +14,6 @@ import AVFoundation
typealias OlderClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Any?) -> Void
typealias NewerClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Bool, Any?) -> Void
-// the message needs to be concatenated with '' in order to have the same behavior like on Android
-let consoleLogJS = """
-(function() {
- var oldLogs = {
- 'consoleLog': console.log,
- 'consoleDebug': console.debug,
- 'consoleError': console.error,
- 'consoleInfo': console.info,
- 'consoleWarn': console.warn
- };
-
- for (var k in oldLogs) {
- (function(oldLog) {
- console[oldLog.replace('console', '').toLowerCase()] = function() {
- var message = '';
- for (var i in arguments) {
- if (message == '') {
- message += arguments[i];
- }
- else {
- message += ' ' + arguments[i];
- }
- }
- window.webkit.messageHandlers[oldLog].postMessage(message);
- }
- })(k);
- }
-})();
-"""
-
-let resourceObserverJS = """
-(function() {
- var observer = new PerformanceObserver(function(list) {
- list.getEntries().forEach(function(entry) {
- window.webkit.messageHandlers['resourceLoaded'].postMessage(JSON.stringify(entry));
- });
- });
- observer.observe({entryTypes: ['resource', 'mark', 'measure']});
-})();
-"""
-
-let JAVASCRIPT_BRIDGE_NAME = "flutter_inappbrowser"
-
-let javaScriptBridgeJS = """
-window.\(JAVASCRIPT_BRIDGE_NAME) = {};
-window.\(JAVASCRIPT_BRIDGE_NAME).callHandler = function(handlerName, ...args) {
- window.webkit.messageHandlers['callHandler'].postMessage( {'handlerName': handlerName, 'args': JSON.stringify(args)} );
-}
-"""
-
-func currentTimeInMilliSeconds() -> Int64 {
- let currentDate = Date()
- let since1970 = currentDate.timeIntervalSince1970
- return Int64(since1970 * 1000)
-}
-
-func convertToDictionary(text: String) -> [String: Any]? {
- if let data = text.data(using: .utf8) {
- do {
- return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
- } catch {
- print(error.localizedDescription)
- }
- }
- return nil
-}
-
//extension WKWebView{
//
// var keyboardDisplayRequiresUserAction: Bool? {
@@ -137,7 +70,7 @@ class InAppWebView_IBWrapper: InAppWebView {
}
}
-class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKUIDelegate, WKNavigationDelegate, UITextFieldDelegate, WKScriptMessageHandler {
+class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKUIDelegate, UITextFieldDelegate {
@IBOutlet var webView: InAppWebView_IBWrapper!
@IBOutlet var closeButton: UIButton!
@@ -156,7 +89,7 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
@IBOutlet var webView_TopFullScreenConstraint: NSLayoutConstraint!
weak var navigationDelegate: SwiftFlutterPlugin?
- var currentURL: URL?
+ var initURL: URL?
var tmpWindow: UIWindow?
var browserOptions: InAppBrowserOptions?
var webViewOptions: InAppWebViewOptions?
@@ -189,12 +122,12 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
override func viewDidLoad() {
super.viewDidLoad()
- webView.uiDelegate = self
- webView.navigationDelegate = self
- webView.scrollView.delegate = self
+// webView.uiDelegate = self
+// webView.navigationDelegate = nil
+// webView.scrollView.delegate = self
urlField.delegate = self
- urlField.text = self.currentURL?.absoluteString
+ urlField.text = self.initURL?.absoluteString
closeButton.addTarget(self, action: #selector(self.close), for: .touchUpInside)
@@ -218,7 +151,7 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
spinner.stopAnimating()
if self.initData == nil {
- loadUrl(url: self.currentURL!, headers: self.initHeaders)
+ loadUrl(url: self.initURL!, headers: self.initHeaders)
}
else {
loadData(data: initData!, mimeType: initMimeType!, encoding: initEncoding!, baseUrl: initBaseUrl!)
@@ -245,13 +178,8 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
func prepareWebView() {
//UIApplication.shared.statusBarStyle = preferredStatusBarStyle
- self.webView.addObserver(self,
- forKeyPath: #keyPath(WKWebView.estimatedProgress),
- options: .new,
- context: nil)
-
- self.webView.configuration.userContentController = WKUserContentController()
- self.webView.configuration.preferences = WKPreferences()
+ self.webView.options = webViewOptions
+ self.webView.prepare()
if (browserOptions?.hideUrlBar)! {
self.urlField.isHidden = true
@@ -290,133 +218,21 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
self.modalPresentationStyle = UIModalPresentationStyle(rawValue: (browserOptions?.presentationStyle)!)!
self.modalTransitionStyle = UIModalTransitionStyle(rawValue: (browserOptions?.transitionStyle)!)!
-
- // prevent webView from bouncing
- if (webViewOptions?.disallowOverScroll)! {
- if self.webView.responds(to: #selector(getter: self.webView.scrollView)) {
- self.webView.scrollView.bounces = false
- }
- else {
- for subview: UIView in self.webView.subviews {
- if subview is UIScrollView {
- (subview as! UIScrollView).bounces = false
- }
- }
- }
- }
-
- if (webViewOptions?.enableViewportScale)! {
- let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
- let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
- self.webView.configuration.userContentController.addUserScript(userScript)
- }
-
- // Prevents long press on links that cause WKWebView exit
- let jscriptWebkitTouchCallout = WKUserScript(source: "document.body.style.webkitTouchCallout='none';", injectionTime: .atDocumentEnd, forMainFrameOnly: true)
- self.webView.configuration.userContentController.addUserScript(jscriptWebkitTouchCallout)
-
-
- let consoleLogJSScript = WKUserScript(source: consoleLogJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
- self.webView.configuration.userContentController.addUserScript(consoleLogJSScript)
- self.webView.configuration.userContentController.add(self, name: "consoleLog")
- self.webView.configuration.userContentController.add(self, name: "consoleDebug")
- self.webView.configuration.userContentController.add(self, name: "consoleError")
- self.webView.configuration.userContentController.add(self, name: "consoleInfo")
- self.webView.configuration.userContentController.add(self, name: "consoleWarn")
-
- let javaScriptBridgeJSScript = WKUserScript(source: javaScriptBridgeJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
- self.webView.configuration.userContentController.addUserScript(javaScriptBridgeJSScript)
- self.webView.configuration.userContentController.add(self, name: "callHandler")
-
- let resourceObserverJSScript = WKUserScript(source: resourceObserverJS, injectionTime: .atDocumentStart, forMainFrameOnly: false)
- self.webView.configuration.userContentController.addUserScript(resourceObserverJSScript)
- self.webView.configuration.userContentController.add(self, name: "resourceLoaded")
-
- if #available(iOS 10.0, *) {
- self.webView.configuration.mediaTypesRequiringUserActionForPlayback = ((webViewOptions?.mediaPlaybackRequiresUserGesture)!) ? .all : []
- } else {
- // Fallback on earlier versions
- self.webView.configuration.mediaPlaybackRequiresUserAction = (webViewOptions?.mediaPlaybackRequiresUserGesture)!
- }
-
-
- self.webView.configuration.allowsInlineMediaPlayback = (webViewOptions?.allowsInlineMediaPlayback)!
-
- //self.webView.keyboardDisplayRequiresUserAction = browserOptions?.keyboardDisplayRequiresUserAction
-
- self.webView.configuration.suppressesIncrementalRendering = (webViewOptions?.suppressesIncrementalRendering)!
- self.webView.allowsBackForwardNavigationGestures = (webViewOptions?.allowsBackForwardNavigationGestures)!
- if #available(iOS 9.0, *) {
- self.webView.allowsLinkPreview = (webViewOptions?.allowsLinkPreview)!
- }
-
- if #available(iOS 10.0, *) {
- self.webView.configuration.ignoresViewportScaleLimits = (webViewOptions?.ignoresViewportScaleLimits)!
- }
-
- self.webView.configuration.allowsInlineMediaPlayback = (webViewOptions?.allowsInlineMediaPlayback)!
-
- if #available(iOS 9.0, *) {
- self.webView.configuration.allowsPictureInPictureMediaPlayback = (webViewOptions?.allowsPictureInPictureMediaPlayback)!
- }
-
- self.webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = (webViewOptions?.javaScriptCanOpenWindowsAutomatically)!
-
- self.webView.configuration.preferences.javaScriptEnabled = (webViewOptions?.javaScriptEnabled)!
-
- if ((webViewOptions?.userAgent)! != "") {
- if #available(iOS 9.0, *) {
- self.webView.customUserAgent = (webViewOptions?.userAgent)!
- }
- }
-
- if (webViewOptions?.clearCache)! {
- clearCache()
- }
-
}
func loadUrl(url: URL, headers: [String: String]?) {
- var request = URLRequest(url: url)
- currentURL = url
- updateUrlTextField(url: (currentURL?.absoluteString)!)
-
- if let mutableRequest = (request as NSURLRequest).mutableCopy() as? NSMutableURLRequest {
- for (key, value) in headers! {
- mutableRequest.setValue(value, forHTTPHeaderField: key)
- }
- request = mutableRequest as URLRequest
- }
-
- webView.load(request)
+ webView.loadUrl(url: url, headers: headers)
+ updateUrlTextField(url: (webView.currentURL?.absoluteString)!)
}
func loadData(data: String, mimeType: String, encoding: String, baseUrl: String) {
- let url = URL(string: baseUrl)!
- currentURL = url
- if #available(iOS 9.0, *) {
- webView.load(data.data(using: .utf8)!, mimeType: mimeType, characterEncodingName: encoding, baseURL: url)
- } else {
- webView.loadHTMLString(data, baseURL: url)
- }
+ webView.loadData(data: data, mimeType: mimeType, encoding: encoding, baseUrl: baseUrl)
}
func postUrl(url: URL, postData: Data, result: @escaping FlutterResult) {
- var request = URLRequest(url: url)
- request.httpMethod = "POST"
- request.httpBody = postData
-
- let task = URLSession.shared.dataTask(with: request) { (data : Data?, response : URLResponse?, error : Error?) in
- var returnString = ""
- if data != nil {
- returnString = String(data: data!, encoding: .utf8) ?? ""
- }
- DispatchQueue.main.async(execute: {() -> Void in
- self.webView.loadHTMLString(returnString, baseURL: url)
- result(true)
- })
- }
- task.resume()
+ webView.postUrl(url: url, postData: postData, completionHandler: { () -> Void in
+ result(true)
+ })
}
// Load user requested url
@@ -428,9 +244,8 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
webView.load(request)
}
else {
- updateUrlTextField(url: (currentURL?.absoluteString)!)
+ updateUrlTextField(url: (webView.currentURL?.absoluteString)!)
}
- //var list : WKBackForwardList = self.webView.backForwardList
return false
}
@@ -439,30 +254,12 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
webView.frame = frame
}
- func clearCache() {
- if #available(iOS 9.0, *) {
- //let websiteDataTypes = NSSet(array: [WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache])
- let date = NSDate(timeIntervalSince1970: 0)
- WKWebsiteDataStore.default().removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), modifiedSince: date as Date, completionHandler:{ })
- } else {
- var libraryPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.libraryDirectory, FileManager.SearchPathDomainMask.userDomainMask, false).first!
- libraryPath += "/Cookies"
-
- do {
- try FileManager.default.removeItem(atPath: libraryPath)
- } catch {
- print("can't clear cache")
- }
- URLCache.shared.removeAllCachedResponses()
- }
- }
-
@objc func reload () {
webView.reload()
}
@objc func share () {
- let vc = UIActivityViewController(activityItems: [currentURL ?? ""], applicationActivities: [])
+ let vc = UIActivityViewController(activityItems: [webView.currentURL ?? ""], applicationActivities: [])
present(vc, animated: true, completion: nil)
}
@@ -569,237 +366,12 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
scanner.scanHexInt32(&hexInt)
return hexInt
}
-
- func webView(_ webView: WKWebView,
- decidePolicyFor navigationAction: WKNavigationAction,
- decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
-
- if let url = navigationAction.request.url {
-
- if url.absoluteString != self.currentURL?.absoluteString && (webViewOptions?.useOnLoadResource)! {
- WKNavigationMap[url.absoluteString] = [
- "startTime": currentTimeInMilliSeconds(),
- "request": navigationAction.request
- ]
- }
-
- if navigationAction.navigationType == .linkActivated && (webViewOptions?.useShouldOverrideUrlLoading)! {
- if navigationDelegate != nil {
- navigationDelegate?.shouldOverrideUrlLoading(uuid: self.uuid, webView: webView, url: url)
- }
- decisionHandler(.cancel)
- return
- }
-
- if navigationAction.navigationType == .linkActivated || navigationAction.navigationType == .backForward {
- currentURL = url
- updateUrlTextField(url: (url.absoluteString))
- }
-
- }
-
-
- decisionHandler(.allow)
- }
-
- func webView(_ webView: WKWebView,
- decidePolicyFor navigationResponse: WKNavigationResponse,
- decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
-
- if (webViewOptions?.useOnLoadResource)! {
- if let url = navigationResponse.response.url {
- if WKNavigationMap[url.absoluteString] != nil {
- let startResourceTime: Int64 = (WKNavigationMap[url.absoluteString]!["startTime"] as! Int64)
- let startTime: Int64 = startResourceTime - startPageTime;
- let duration: Int64 = currentTimeInMilliSeconds() - startResourceTime;
- self.didReceiveResourceResponse(navigationResponse.response, fromRequest: WKNavigationMap[url.absoluteString]!["request"] as? URLRequest, withData: Data(), startTime: startTime, duration: duration)
- }
- }
- }
-
- decisionHandler(.allow)
- }
-
-// func webView(_ webView: WKWebView,
-// decidePolicyFor navigationResponse: WKNavigationResponse,
-// decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
-// let mimeType = navigationResponse.response.mimeType
-// if mimeType != nil && !mimeType!.starts(with: "text/") {
-// download(url: webView.url)
-// decisionHandler(.cancel)
-// return
-// }
-// decisionHandler(.allow)
-// }
-//
-// func download (url: URL?) {
-// let filename = url?.lastPathComponent
-//
-// let destination: DownloadRequest.DownloadFileDestination = { _, _ in
-// let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
-// let fileURL = documentsURL.appendingPathComponent(filename!)
-//
-// return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
-// }
-//
-// Alamofire.download((url?.absoluteString)!, to: destination).downloadProgress { progress in
-// print("Download Progress: \(progress.fractionCompleted)")
-// }.response { response in
-// if response.error == nil, let path = response.destinationURL?.path {
-// UIAlertView(title: nil, message: "File saved to " + path, delegate: nil, cancelButtonTitle: nil).show()
-// }
-// else {
-// UIAlertView(title: nil, message: "Cannot save " + filename!, delegate: nil, cancelButtonTitle: nil).show()
-// }
-// }
-// }
-
- func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
-
- self.startPageTime = currentTimeInMilliSeconds()
-
- // loading url, start spinner, update back/forward
- backButton.isEnabled = webView.canGoBack
- forwardButton.isEnabled = webView.canGoForward
-
- if (browserOptions?.spinner)! {
- spinner.startAnimating()
- }
-
- if navigationDelegate != nil {
- navigationDelegate?.onLoadStart(uuid: self.uuid, webView: webView)
- }
- }
-
- func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
- self.WKNavigationMap = [:]
- // update url, stop spinner, update back/forward
- currentURL = webView.url
- updateUrlTextField(url: (currentURL?.absoluteString)!)
- backButton.isEnabled = webView.canGoBack
- forwardButton.isEnabled = webView.canGoForward
- spinner.stopAnimating()
-
- if navigationDelegate != nil {
- navigationDelegate?.onLoadStop(uuid: self.uuid, webView: webView)
- }
- }
-
- func webView(_ view: WKWebView,
- didFailProvisionalNavigation navigation: WKNavigation!,
- withError error: Error) {
- webView(view, didFail: navigation, withError: error)
- }
-
- func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
- backButton.isEnabled = webView.canGoBack
- forwardButton.isEnabled = webView.canGoForward
- spinner.stopAnimating()
-
- if navigationDelegate != nil {
- navigationDelegate?.onLoadError(uuid: self.uuid, webView: webView, error: error)
- }
- }
-
- func didReceiveResourceResponse(_ response: URLResponse, fromRequest request: URLRequest?, withData data: Data, startTime: Int64, duration: Int64) {
- if navigationDelegate != nil {
- navigationDelegate?.onLoadResource(uuid: self.uuid, webView: webView, response: response, fromRequest: request, withData: data, startTime: startTime, duration: duration)
- }
- }
-
- func scrollViewDidScroll(_ scrollView: UIScrollView) {
- if navigationDelegate != nil {
- let x = Int(scrollView.contentOffset.x / scrollView.contentScaleFactor)
- let y = Int(scrollView.contentOffset.y / scrollView.contentScaleFactor)
- navigationDelegate?.onScrollChanged(uuid: self.uuid, webView: webView, x: x, y: y)
- }
- }
-
- func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
- if message.name.starts(with: "console") {
- var messageLevel = "LOG"
- switch (message.name) {
- case "consoleLog":
- messageLevel = "LOG"
- break;
- case "consoleDebug":
- // on Android, console.debug is TIP
- messageLevel = "TIP"
- break;
- case "consoleError":
- messageLevel = "ERROR"
- break;
- case "consoleInfo":
- // on Android, console.info is LOG
- messageLevel = "LOG"
- break;
- case "consoleWarn":
- messageLevel = "WARNING"
- break;
- default:
- messageLevel = "LOG"
- break;
- }
- if navigationDelegate != nil {
- navigationDelegate?.onConsoleMessage(uuid: self.uuid, sourceURL: "", lineNumber: 1, message: message.body as! String, messageLevel: messageLevel)
- }
- }
- else if message.name == "resourceLoaded" && (webViewOptions?.useOnLoadResource)! {
- if let resource = convertToDictionary(text: message.body as! String) {
- let rawUrl = resource["name"] as! String
- let encodedUrl = rawUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
- let url = URL(string: encodedUrl)!
- if !UIApplication.shared.canOpenURL(url) {
- return
- }
- let startTime = Int64(resource["startTime"] as! Double)
- let duration = Int64(resource["duration"] as! Double)
- var urlRequest = URLRequest(url: url)
- urlRequest.allHTTPHeaderFields = [:]
- let config = URLSessionConfiguration.default
- let session = URLSession(configuration: config)
- let task = session.dataTask(with: urlRequest) { (data, response, error) in
- if error != nil {
- print(error)
- return
- }
- var withData = data
- if withData == nil {
- withData = Data()
- }
- self.didReceiveResourceResponse(response!, fromRequest: urlRequest, withData: withData!, startTime: startTime, duration: duration)
- }
- task.resume()
- }
- }
- else if message.name == "callHandler" {
- let body = message.body as! [String: Any]
- let handlerName = body["handlerName"] as! String
- let args = body["args"] as! String
- if navigationDelegate != nil {
- self.navigationDelegate?.onCallJsHandler(uuid: self.uuid, webView: webView, handlerName: handlerName, args: args)
- }
- }
- }
-
- func takeScreenshot (completionHandler: @escaping (_ screenshot: Data?) -> Void) {
- if #available(iOS 11.0, *) {
- self.webView.takeSnapshot(with: nil, completionHandler: {(image, error) -> Void in
- var imageData: Data? = nil
- if let screenshot = image {
- imageData = UIImagePNGRepresentation(screenshot)!
- }
- completionHandler(imageData)
- })
- } else {
- completionHandler(nil)
- }
- }
func setOptions(newOptions: InAppBrowserOptions, newOptionsMap: [String: Any]) {
let newInAppWebViewOptions = InAppWebViewOptions()
newInAppWebViewOptions.parse(options: newOptionsMap)
+ self.webView.setOptions(newOptions: newInAppWebViewOptions, newOptionsMap: newOptionsMap)
if newOptionsMap["hidden"] != nil && browserOptions?.hidden != newOptions.hidden {
if newOptions.hidden {
@@ -854,135 +426,18 @@ class InAppBrowserWebViewController: UIViewController, UIScrollViewDelegate, WKU
if newOptionsMap["transitionStyle"] != nil && browserOptions?.transitionStyle != newOptions.transitionStyle {
self.modalTransitionStyle = UIModalTransitionStyle(rawValue: newOptions.transitionStyle)!
}
-
- if newOptionsMap["disallowOverScroll"] != nil && webViewOptions?.disallowOverScroll != newInAppWebViewOptions.disallowOverScroll {
- if self.webView.responds(to: #selector(getter: self.webView.scrollView)) {
- self.webView.scrollView.bounces = !newInAppWebViewOptions.disallowOverScroll
- }
- else {
- for subview: UIView in self.webView.subviews {
- if subview is UIScrollView {
- (subview as! UIScrollView).bounces = !newInAppWebViewOptions.disallowOverScroll
- }
- }
- }
- }
-
- if newOptionsMap["enableViewportScale"] != nil && webViewOptions?.enableViewportScale != newInAppWebViewOptions.enableViewportScale && newInAppWebViewOptions.enableViewportScale {
- let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
- self.webView.evaluateJavaScript(jscript, completionHandler: nil)
- }
-
- if newOptionsMap["mediaPlaybackRequiresUserGesture"] != nil && webViewOptions?.mediaPlaybackRequiresUserGesture != newInAppWebViewOptions.mediaPlaybackRequiresUserGesture {
- if #available(iOS 10.0, *) {
- self.webView.configuration.mediaTypesRequiringUserActionForPlayback = (newInAppWebViewOptions.mediaPlaybackRequiresUserGesture) ? .all : []
- } else {
- // Fallback on earlier versions
- self.webView.configuration.mediaPlaybackRequiresUserAction = newInAppWebViewOptions.mediaPlaybackRequiresUserGesture
- }
- }
-
- if newOptionsMap["allowsInlineMediaPlayback"] != nil && webViewOptions?.allowsInlineMediaPlayback != newInAppWebViewOptions.allowsInlineMediaPlayback {
- self.webView.configuration.allowsInlineMediaPlayback = newInAppWebViewOptions.allowsInlineMediaPlayback
- }
-
-// if newOptionsMap["keyboardDisplayRequiresUserAction"] != nil && browserOptions?.keyboardDisplayRequiresUserAction != newOptions.keyboardDisplayRequiresUserAction {
-// self.webView.keyboardDisplayRequiresUserAction = newOptions.keyboardDisplayRequiresUserAction
-// }
-
- if newOptionsMap["suppressesIncrementalRendering"] != nil && webViewOptions?.suppressesIncrementalRendering != newInAppWebViewOptions.suppressesIncrementalRendering {
- self.webView.configuration.suppressesIncrementalRendering = newInAppWebViewOptions.suppressesIncrementalRendering
- }
-
- if newOptionsMap["allowsBackForwardNavigationGestures"] != nil && webViewOptions?.allowsBackForwardNavigationGestures != newInAppWebViewOptions.allowsBackForwardNavigationGestures {
- self.webView.allowsBackForwardNavigationGestures = newInAppWebViewOptions.allowsBackForwardNavigationGestures
- }
-
- if newOptionsMap["allowsLinkPreview"] != nil && webViewOptions?.allowsLinkPreview != newInAppWebViewOptions.allowsLinkPreview {
- if #available(iOS 9.0, *) {
- self.webView.allowsLinkPreview = newInAppWebViewOptions.allowsLinkPreview
- }
- }
-
- if newOptionsMap["ignoresViewportScaleLimits"] != nil && webViewOptions?.ignoresViewportScaleLimits != newInAppWebViewOptions.ignoresViewportScaleLimits {
- if #available(iOS 10.0, *) {
- self.webView.configuration.ignoresViewportScaleLimits = newInAppWebViewOptions.ignoresViewportScaleLimits
- }
- }
-
- if newOptionsMap["allowsInlineMediaPlayback"] != nil && webViewOptions?.allowsInlineMediaPlayback != newInAppWebViewOptions.allowsInlineMediaPlayback {
- self.webView.configuration.allowsInlineMediaPlayback = newInAppWebViewOptions.allowsInlineMediaPlayback
- }
-
- if newOptionsMap["allowsPictureInPictureMediaPlayback"] != nil && webViewOptions?.allowsPictureInPictureMediaPlayback != newInAppWebViewOptions.allowsPictureInPictureMediaPlayback {
- if #available(iOS 9.0, *) {
- self.webView.configuration.allowsPictureInPictureMediaPlayback = newInAppWebViewOptions.allowsPictureInPictureMediaPlayback
- }
- }
-
- if newOptionsMap["javaScriptCanOpenWindowsAutomatically"] != nil && webViewOptions?.javaScriptCanOpenWindowsAutomatically != newInAppWebViewOptions.javaScriptCanOpenWindowsAutomatically {
- self.webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = newInAppWebViewOptions.javaScriptCanOpenWindowsAutomatically
- }
-
- if newOptionsMap["javaScriptEnabled"] != nil && webViewOptions?.javaScriptEnabled != newInAppWebViewOptions.javaScriptEnabled {
- self.webView.configuration.preferences.javaScriptEnabled = newInAppWebViewOptions.javaScriptEnabled
- }
-
- if newOptionsMap["userAgent"] != nil && webViewOptions?.userAgent != newInAppWebViewOptions.userAgent && (newInAppWebViewOptions.userAgent != "") {
- if #available(iOS 9.0, *) {
- self.webView.customUserAgent = newInAppWebViewOptions.userAgent
- }
- }
-
- if newOptionsMap["clearCache"] != nil && newInAppWebViewOptions.clearCache {
- clearCache()
- }
self.browserOptions = newOptions
self.webViewOptions = newInAppWebViewOptions
}
func getOptions() -> [String: Any]? {
- if (self.browserOptions == nil || self.webViewOptions == nil) {
+ if (self.browserOptions == nil || self.webView.getOptions() == nil) {
return nil
}
var optionsMap = self.browserOptions!.getHashMap()
- optionsMap.merge(self.webViewOptions!.getHashMap(), uniquingKeysWith: { (current, _) in current })
+ optionsMap.merge(self.webView.getOptions()!, uniquingKeysWith: { (current, _) in current })
return optionsMap
}
-
- override func observeValue(forKeyPath keyPath: String?, of object: Any?,
- change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
- if keyPath == "estimatedProgress" {
- let progress = Int(webView.estimatedProgress * 100)
- self.navigationDelegate?.onProgressChanged(uuid: self.uuid, webView: self.webView, progress: progress)
- }
- }
-
- func getCopyBackForwardList() -> [String: Any] {
- let currentList = self.webView.backForwardList
- let currentIndex = currentList.backList.count
- var completeList = currentList.backList
- if currentList.currentItem != nil {
- completeList.append(currentList.currentItem!)
- }
- completeList.append(contentsOf: currentList.forwardList)
-
- var history: [[String: String]] = []
-
- for historyItem in completeList {
- var historyItemMap: [String: String] = [:]
- historyItemMap["originalUrl"] = historyItem.initialURL.absoluteString
- historyItemMap["title"] = historyItem.title
- historyItemMap["url"] = historyItem.url.absoluteString
- history.append(historyItemMap)
- }
-
- var result: [String: Any] = [:]
- result["history"] = history
- result["currentIndex"] = currentIndex
-
- return result;
- }
}
diff --git a/ios/Classes/InAppWebView.swift b/ios/Classes/InAppWebView.swift
index f80faa39..5e3d0b4b 100644
--- a/ios/Classes/InAppWebView.swift
+++ b/ios/Classes/InAppWebView.swift
@@ -8,6 +8,73 @@
import Foundation
import WebKit
+func currentTimeInMilliSeconds() -> Int64 {
+ let currentDate = Date()
+ let since1970 = currentDate.timeIntervalSince1970
+ return Int64(since1970 * 1000)
+}
+
+func convertToDictionary(text: String) -> [String: Any]? {
+ if let data = text.data(using: .utf8) {
+ do {
+ return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
+ } catch {
+ print(error.localizedDescription)
+ }
+ }
+ return nil
+}
+
+// the message needs to be concatenated with '' in order to have the same behavior like on Android
+let consoleLogJS = """
+(function() {
+ var oldLogs = {
+ 'consoleLog': console.log,
+ 'consoleDebug': console.debug,
+ 'consoleError': console.error,
+ 'consoleInfo': console.info,
+ 'consoleWarn': console.warn
+ };
+
+ for (var k in oldLogs) {
+ (function(oldLog) {
+ console[oldLog.replace('console', '').toLowerCase()] = function() {
+ var message = '';
+ for (var i in arguments) {
+ if (message == '') {
+ message += arguments[i];
+ }
+ else {
+ message += ' ' + arguments[i];
+ }
+ }
+ window.webkit.messageHandlers[oldLog].postMessage(message);
+ }
+ })(k);
+ }
+})();
+"""
+
+let resourceObserverJS = """
+(function() {
+ var observer = new PerformanceObserver(function(list) {
+ list.getEntries().forEach(function(entry) {
+ window.webkit.messageHandlers['resourceLoaded'].postMessage(JSON.stringify(entry));
+ });
+ });
+ observer.observe({entryTypes: ['resource', 'mark', 'measure']});
+})();
+"""
+
+let JAVASCRIPT_BRIDGE_NAME = "flutter_inappbrowser"
+
+let javaScriptBridgeJS = """
+window.\(JAVASCRIPT_BRIDGE_NAME) = {};
+window.\(JAVASCRIPT_BRIDGE_NAME).callHandler = function(handlerName, ...args) {
+ window.webkit.messageHandlers['callHandler'].postMessage( {'handlerName': handlerName, 'args': JSON.stringify(args)} );
+}
+"""
+
public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler {
var IABController: InAppBrowserWebViewController?
@@ -87,7 +154,6 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
configuration.mediaPlaybackRequiresUserAction = (options?.mediaPlaybackRequiresUserGesture)!
}
-
configuration.allowsInlineMediaPlayback = (options?.allowsInlineMediaPlayback)!
//keyboardDisplayRequiresUserAction = browserOptions?.keyboardDisplayRequiresUserAction
@@ -436,6 +502,9 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
if navigationAction.navigationType == .linkActivated || navigationAction.navigationType == .backForward {
currentURL = url
+ if IABController != nil {
+ IABController!.updateUrlTextField(url: (currentURL?.absoluteString)!)
+ }
}
}
@@ -460,14 +529,66 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
decisionHandler(.allow)
}
+ // func webView(_ webView: WKWebView,
+ // decidePolicyFor navigationResponse: WKNavigationResponse,
+ // decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
+ // let mimeType = navigationResponse.response.mimeType
+ // if mimeType != nil && !mimeType!.starts(with: "text/") {
+ // download(url: webView.url)
+ // decisionHandler(.cancel)
+ // return
+ // }
+ // decisionHandler(.allow)
+ // }
+ //
+ // func download (url: URL?) {
+ // let filename = url?.lastPathComponent
+ //
+ // let destination: DownloadRequest.DownloadFileDestination = { _, _ in
+ // let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
+ // let fileURL = documentsURL.appendingPathComponent(filename!)
+ //
+ // return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
+ // }
+ //
+ // Alamofire.download((url?.absoluteString)!, to: destination).downloadProgress { progress in
+ // print("Download Progress: \(progress.fractionCompleted)")
+ // }.response { response in
+ // if response.error == nil, let path = response.destinationURL?.path {
+ // UIAlertView(title: nil, message: "File saved to " + path, delegate: nil, cancelButtonTitle: nil).show()
+ // }
+ // else {
+ // UIAlertView(title: nil, message: "Cannot save " + filename!, delegate: nil, cancelButtonTitle: nil).show()
+ // }
+ // }
+ // }
+
public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
self.startPageTime = currentTimeInMilliSeconds()
onLoadStart(url: (currentURL?.absoluteString)!)
+
+ if IABController != nil {
+ // loading url, start spinner, update back/forward
+ IABController!.backButton.isEnabled = canGoBack
+ IABController!.forwardButton.isEnabled = canGoForward
+
+ if (IABController!.browserOptions?.spinner)! {
+ IABController!.spinner.startAnimating()
+ }
+ }
}
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.WKNavigationMap = [:]
- onLoadStop(url: (url?.absoluteString)!)
+ currentURL = url
+ onLoadStop(url: (currentURL?.absoluteString)!)
+
+ if IABController != nil {
+ IABController!.updateUrlTextField(url: (currentURL?.absoluteString)!)
+ IABController!.backButton.isEnabled = canGoBack
+ IABController!.forwardButton.isEnabled = canGoForward
+ IABController!.spinner.stopAnimating()
+ }
}
public func webView(_ view: WKWebView,
@@ -478,6 +599,12 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
onLoadError(url: (currentURL?.absoluteString)!, error: error)
+
+ if IABController != nil {
+ IABController!.backButton.isEnabled = canGoBack
+ IABController!.forwardButton.isEnabled = canGoForward
+ IABController!.spinner.stopAnimating()
+ }
}
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
@@ -609,7 +736,10 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
}
else if message.name == "resourceLoaded" && (options?.useOnLoadResource)! {
if let resource = convertToDictionary(text: message.body as! String) {
- let url = URL(string: resource["name"] as! String)!
+ // escape special chars
+ let resourceName = (resource["name"] as! String).addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
+
+ let url = URL(string: resourceName!)!
if !UIApplication.shared.canOpenURL(url) {
return
}
diff --git a/ios/Classes/SwiftFlutterPlugin.swift b/ios/Classes/SwiftFlutterPlugin.swift
index 30ef86ba..ad5af94e 100644
--- a/ios/Classes/SwiftFlutterPlugin.swift
+++ b/ios/Classes/SwiftFlutterPlugin.swift
@@ -211,7 +211,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
break
case "takeScreenshot":
if let webViewController = self.webViewControllers[uuid] {
- webViewController!.takeScreenshot(completionHandler: { (screenshot) -> Void in
+ webViewController!.webView.takeScreenshot(completionHandler: { (screenshot) -> Void in
result(screenshot)
})
}
@@ -420,7 +420,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
webViewController.webViewOptions = webViewOptions
webViewController.isHidden = browserOptions.hidden
webViewController.tmpWindow = tmpWindow
- webViewController.currentURL = url
+ webViewController.initURL = url
webViewController.initHeaders = headers
webViewController.navigationDelegate = self
@@ -708,21 +708,21 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
func onLoadStart(uuid: String, webView: WKWebView) {
if let webViewController = self.webViewControllers[uuid] {
- let url: String = webViewController!.currentURL!.absoluteString
+ let url: String = webViewController!.webView.currentURL!.absoluteString
SwiftFlutterPlugin.channel!.invokeMethod("onLoadStart", arguments: ["uuid": uuid, "url": url])
}
}
func onLoadStop(uuid: String, webView: WKWebView) {
if let webViewController = self.webViewControllers[uuid] {
- let url: String = webViewController!.currentURL!.absoluteString
+ let url: String = webViewController!.webView.currentURL!.absoluteString
SwiftFlutterPlugin.channel!.invokeMethod("onLoadStop", arguments: ["uuid": uuid, "url": url])
}
}
func onLoadError(uuid: String, webView: WKWebView, error: Error) {
if let webViewController = self.webViewControllers[uuid] {
- let url: String = webViewController!.currentURL!.absoluteString
+ let url: String = webViewController!.webView.currentURL!.absoluteString
let arguments = ["uuid": uuid, "url": url, "code": error._code, "message": error.localizedDescription] as [String : Any]
SwiftFlutterPlugin.channel!.invokeMethod("onLoadError", arguments: arguments)
}
@@ -846,7 +846,7 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
func getCopyBackForwardList(uuid: String) -> [String: Any]? {
if let webViewController = self.webViewControllers[uuid] {
- return webViewController!.getCopyBackForwardList()
+ return webViewController!.webView.getCopyBackForwardList()
}
return nil
}
diff --git a/pubspec.yaml b/pubspec.yaml
index 8dc7b493..4dbb80f9 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: flutter_inappbrowser
description: A Flutter plugin that allows you to add an inline webview or open an in-app browser window (inspired by the popular cordova-plugin-inappbrowser).
-version: 0.5.51
+version: 0.6.0
author: Lorenzo Pichilli
homepage: https://github.com/pichillilorenzo/flutter_inappbrowser
@@ -11,7 +11,7 @@ environment:
dependencies:
flutter:
sdk: flutter
- uuid: ^1.0.3
+ uuid: ^2.0.0
mime: ^0.9.6+2
# For information on the generic Dart part of this file, see the