added createWebArchiveData iOS-specific WebView method, Moved saveWebArchive WebView method from Android-specific to cross-platform
This commit is contained in:
parent
b15ae759d5
commit
88bfe9036f
|
@ -10,7 +10,7 @@
|
||||||
- Added `addUserScript`, `addUserScripts`, `removeUserScript`, `removeUserScripts`, `removeAllUserScripts`, `callAsyncJavaScript` WebView methods
|
- Added `addUserScript`, `addUserScripts`, `removeUserScript`, `removeUserScripts`, `removeAllUserScripts`, `callAsyncJavaScript` WebView methods
|
||||||
- Added `contentWorld` argument to `evaluateJavascript` WebView method
|
- Added `contentWorld` argument to `evaluateJavascript` WebView method
|
||||||
- Added `isDirectionalLockEnabled`, `mediaType`, `pageZoom`, `limitsNavigationsToAppBoundDomains` iOS-specific WebView options
|
- Added `isDirectionalLockEnabled`, `mediaType`, `pageZoom`, `limitsNavigationsToAppBoundDomains` iOS-specific WebView options
|
||||||
- Added `handlesURLScheme`, `createPdf` iOS-specific WebView methods
|
- Added `handlesURLScheme`, `createPdf`, `createWebArchiveData` iOS-specific WebView methods
|
||||||
- Added `iosAnimated` optional argument to `zoomBy` WebView method
|
- Added `iosAnimated` optional argument to `zoomBy` WebView method
|
||||||
- Added `screenshotConfiguration` optional argument to `takeScreenshot` WebView method
|
- Added `screenshotConfiguration` optional argument to `takeScreenshot` WebView method
|
||||||
- Updated integration tests
|
- Updated integration tests
|
||||||
|
@ -44,6 +44,7 @@
|
||||||
- `allowUniversalAccessFromFileURLs` and `allowFileAccessFromFileURLs` WebView options moved from Android-specific options to cross-platform options
|
- `allowUniversalAccessFromFileURLs` and `allowFileAccessFromFileURLs` WebView options moved from Android-specific options to cross-platform options
|
||||||
- Added `callAsyncJavaScript` name to the list of javaScriptHandlerForbiddenNames
|
- Added `callAsyncJavaScript` name to the list of javaScriptHandlerForbiddenNames
|
||||||
- Changed `zoomBy` WebView method signature
|
- Changed `zoomBy` WebView method signature
|
||||||
|
- Moved `saveWebArchive` WebView method from Android-specific to cross-platform
|
||||||
|
|
||||||
## 4.0.0+4
|
## 4.0.0+4
|
||||||
|
|
||||||
|
|
|
@ -494,6 +494,7 @@ Android-specific methods can be called using the `InAppWebViewController.android
|
||||||
iOS-specific methods can be called using the `InAppWebViewController.ios` attribute. Static methods can be called using the `IOSInAppWebViewController` class directly.
|
iOS-specific methods can be called using the `InAppWebViewController.ios` attribute. Static methods can be called using the `IOSInAppWebViewController` class directly.
|
||||||
|
|
||||||
* `createPdf({IOSWKPDFConfiguration? iosWKPdfConfiguration})`: Generates PDF data from the web view’s contents asynchronously.
|
* `createPdf({IOSWKPDFConfiguration? iosWKPdfConfiguration})`: Generates PDF data from the web view’s contents asynchronously.
|
||||||
|
* `createWebArchiveData`: Creates a web archive of the web view’s current contents asynchronously.
|
||||||
* `hasOnlySecureContent`: A Boolean value indicating whether all resources on the page have been loaded over securely encrypted connections.
|
* `hasOnlySecureContent`: A Boolean value indicating whether all resources on the page have been loaded over securely encrypted connections.
|
||||||
* `reloadFromOrigin`: Reloads the current page, performing end-to-end revalidation using cache-validating conditionals if possible.
|
* `reloadFromOrigin`: Reloads the current page, performing end-to-end revalidation using cache-validating conditionals if possible.
|
||||||
* `static handlesURLScheme(String urlScheme)`: Returns a Boolean value that indicates whether WebKit natively supports resources with the specified URL scheme.
|
* `static handlesURLScheme(String urlScheme)`: Returns a Boolean value that indicates whether WebKit natively supports resources with the specified URL scheme.
|
||||||
|
|
|
@ -338,9 +338,9 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
|
||||||
break;
|
break;
|
||||||
case "saveWebArchive":
|
case "saveWebArchive":
|
||||||
if (webView != null) {
|
if (webView != null) {
|
||||||
String basename = (String) call.argument("basename");
|
String filePath = (String) call.argument("filePath");
|
||||||
boolean autoname = (boolean) call.argument("autoname");
|
boolean autoname = (boolean) call.argument("autoname");
|
||||||
webView.saveWebArchive(basename, autoname, new ValueCallback<String>() {
|
webView.saveWebArchive(filePath, autoname, new ValueCallback<String>() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceiveValue(String value) {
|
public void onReceiveValue(String value) {
|
||||||
result.success(value);
|
result.success(value);
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.pub-cache/git/plugins-16f3281b04b0db12e609352b1c9544901392e428/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1+1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.4/","dependencies":[]}],"android":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.pub-cache/git/plugins-16f3281b04b0db12e609352b1c9544901392e428/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1+1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.4/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+8/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+2/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.0.4+3/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-0.1.0-nullsafety.2/","dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"device_info","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":["device_info"]},{"name":"integration_test","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-02-08 18:26:05.315620","version":"1.26.0-18.0.pre.90"}
|
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.pub-cache/git/plugins-16f3281b04b0db12e609352b1c9544901392e428/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1+1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.4/","dependencies":[]}],"android":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.pub-cache/git/plugins-16f3281b04b0db12e609352b1c9544901392e428/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1+1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.4/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+8/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+2/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.0.4+3/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-0.1.0-nullsafety.2/","dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"device_info","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":["device_info"]},{"name":"integration_test","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-02-09 01:23:18.308862","version":"1.26.0-18.0.pre.90"}
|
|
@ -262,7 +262,6 @@
|
||||||
"${BUILT_PRODUCTS_DIR}/flutter_inappwebview/flutter_inappwebview.framework",
|
"${BUILT_PRODUCTS_DIR}/flutter_inappwebview/flutter_inappwebview.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework",
|
"${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
|
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/pdf_viewer_plugin/pdf_viewer_plugin.framework",
|
|
||||||
"${BUILT_PRODUCTS_DIR}/url_launcher/url_launcher.framework",
|
"${BUILT_PRODUCTS_DIR}/url_launcher/url_launcher.framework",
|
||||||
);
|
);
|
||||||
name = "[CP] Embed Pods Frameworks";
|
name = "[CP] Embed Pods Frameworks";
|
||||||
|
@ -272,7 +271,6 @@
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_inappwebview.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_inappwebview.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/pdf_viewer_plugin.framework",
|
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher.framework",
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>NSDocumentsFolderUsageDescription</key>
|
||||||
|
<string>InAppWebView requires access to documents folder</string>
|
||||||
<key>NSMicrophoneUsageDescription</key>
|
<key>NSMicrophoneUsageDescription</key>
|
||||||
<string>InAppWebView requires acess to mic.</string>
|
<string>InAppWebView requires access to mic.</string>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>en</string>
|
<string>en</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
|
@ -64,7 +66,7 @@
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>NSCameraUsageDescription</key>
|
<key>NSCameraUsageDescription</key>
|
||||||
<string>InAppWebView requires acess to cam.</string>
|
<string>InAppWebView requires access to cam.</string>
|
||||||
<key>NSLocalNetworkUsageDescription</key>
|
<key>NSLocalNetworkUsageDescription</key>
|
||||||
<string>Allow Flutter tools on your computer to connect and debug your application.</string>
|
<string>Allow Flutter tools on your computer to connect and debug your application.</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
|
// import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
import 'main.dart';
|
import 'main.dart';
|
||||||
|
|
|
@ -18,6 +18,7 @@ Future main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
// await Permission.camera.request();
|
// await Permission.camera.request();
|
||||||
// await Permission.microphone.request();
|
// await Permission.microphone.request();
|
||||||
|
// await Permission.storage.request();
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
|
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
|
||||||
|
|
||||||
|
|
|
@ -1700,8 +1700,8 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
: currentIndex + steps >= 0
|
: currentIndex + steps >= 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(iOS 11.0, *)
|
||||||
public func takeScreenshot (with: [String: Any?]?, completionHandler: @escaping (_ screenshot: Data?) -> Void) {
|
public func takeScreenshot (with: [String: Any?]?, completionHandler: @escaping (_ screenshot: Data?) -> Void) {
|
||||||
if #available(iOS 11.0, *) {
|
|
||||||
var snapshotConfiguration: WKSnapshotConfiguration? = nil
|
var snapshotConfiguration: WKSnapshotConfiguration? = nil
|
||||||
if let with = with {
|
if let with = with {
|
||||||
snapshotConfiguration = WKSnapshotConfiguration()
|
snapshotConfiguration = WKSnapshotConfiguration()
|
||||||
|
@ -1737,13 +1737,10 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
}
|
}
|
||||||
completionHandler(imageData)
|
completionHandler(imageData)
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
completionHandler(nil)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(iOS 14.0, *)
|
||||||
public func createPdf (configuration: [String: Any?]?, completionHandler: @escaping (_ pdf: Data?) -> Void) {
|
public func createPdf (configuration: [String: Any?]?, completionHandler: @escaping (_ pdf: Data?) -> Void) {
|
||||||
if #available(iOS 14.0, *) {
|
|
||||||
let pdfConfiguration: WKPDFConfiguration = .init()
|
let pdfConfiguration: WKPDFConfiguration = .init()
|
||||||
if let configuration = configuration {
|
if let configuration = configuration {
|
||||||
if let rect = configuration["rect"] as? [String: Double] {
|
if let rect = configuration["rect"] as? [String: Double] {
|
||||||
|
@ -1761,9 +1758,59 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 14.0, *)
|
||||||
|
public func createWebArchiveData (dataCompletionHandler: @escaping (_ webArchiveData: Data?) -> Void) {
|
||||||
|
createWebArchiveData(completionHandler: { (result) in
|
||||||
|
switch (result) {
|
||||||
|
case .success(let data):
|
||||||
|
dataCompletionHandler(data)
|
||||||
|
return
|
||||||
|
case .failure(let error):
|
||||||
|
print(error.localizedDescription)
|
||||||
|
dataCompletionHandler(nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 14.0, *)
|
||||||
|
public func saveWebArchive (filePath: String, autoname: Bool, completionHandler: @escaping (_ path: String?) -> Void) {
|
||||||
|
createWebArchiveData(dataCompletionHandler: { (webArchiveData) in
|
||||||
|
if let webArchiveData = webArchiveData {
|
||||||
|
var localUrl = URL(fileURLWithPath: filePath)
|
||||||
|
if autoname {
|
||||||
|
if let url = self.url {
|
||||||
|
// tries to mimic Android saveWebArchive method
|
||||||
|
let invalidCharacters = CharacterSet(charactersIn: "\\/:*?\"<>|")
|
||||||
|
.union(.newlines)
|
||||||
|
.union(.illegalCharacters)
|
||||||
|
.union(.controlCharacters)
|
||||||
|
|
||||||
|
let currentPageUrlFileName = url.path
|
||||||
|
.components(separatedBy: invalidCharacters)
|
||||||
|
.joined(separator: "")
|
||||||
|
|
||||||
|
let fullPath = filePath + "/" + currentPageUrlFileName + ".webarchive"
|
||||||
|
localUrl = URL(fileURLWithPath: fullPath)
|
||||||
|
} else {
|
||||||
|
completionHandler(nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
try webArchiveData.write(to: localUrl)
|
||||||
|
completionHandler(localUrl.path)
|
||||||
|
} catch {
|
||||||
|
// Catch any errors
|
||||||
|
print(error.localizedDescription)
|
||||||
|
completionHandler(nil)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
completionHandler(nil)
|
completionHandler(nil)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public func loadUrl(url: URL, headers: [String: String]?) {
|
public func loadUrl(url: URL, headers: [String: String]?) {
|
||||||
|
|
|
@ -128,7 +128,7 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
||||||
result(webView?.isLoading ?? false)
|
result(webView?.isLoading ?? false)
|
||||||
break
|
break
|
||||||
case "takeScreenshot":
|
case "takeScreenshot":
|
||||||
if webView != nil {
|
if webView != nil, #available(iOS 11.0, *) {
|
||||||
let screenshotConfiguration = arguments!["screenshotConfiguration"] as? [String: Any?]
|
let screenshotConfiguration = arguments!["screenshotConfiguration"] as? [String: Any?]
|
||||||
webView!.takeScreenshot(with: screenshotConfiguration, completionHandler: { (screenshot) -> Void in
|
webView!.takeScreenshot(with: screenshotConfiguration, completionHandler: { (screenshot) -> Void in
|
||||||
result(screenshot)
|
result(screenshot)
|
||||||
|
@ -403,7 +403,7 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case "createPdf":
|
case "createPdf":
|
||||||
if webView != nil {
|
if webView != nil, #available(iOS 14.0, *) {
|
||||||
let configuration = arguments!["iosWKPdfConfiguration"] as? [String: Any?]
|
let configuration = arguments!["iosWKPdfConfiguration"] as? [String: Any?]
|
||||||
webView!.createPdf(configuration: configuration, completionHandler: { (pdf) -> Void in
|
webView!.createPdf(configuration: configuration, completionHandler: { (pdf) -> Void in
|
||||||
result(pdf)
|
result(pdf)
|
||||||
|
@ -413,6 +413,28 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
||||||
result(nil)
|
result(nil)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case "createWebArchiveData":
|
||||||
|
if webView != nil, #available(iOS 14.0, *) {
|
||||||
|
webView!.createWebArchiveData(dataCompletionHandler: { (webArchiveData) -> Void in
|
||||||
|
result(webArchiveData)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result(nil)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case "saveWebArchive":
|
||||||
|
if webView != nil, #available(iOS 14.0, *) {
|
||||||
|
let filePath = arguments!["filePath"] as! String
|
||||||
|
let autoname = arguments!["autoname"] as! Bool
|
||||||
|
webView!.saveWebArchive(filePath: filePath, autoname: autoname, completionHandler: { (path) -> Void in
|
||||||
|
result(path)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result(nil)
|
||||||
|
}
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
result(FlutterMethodNotImplemented)
|
result(FlutterMethodNotImplemented)
|
||||||
break
|
break
|
||||||
|
|
|
@ -1508,7 +1508,7 @@ class InAppWebViewController {
|
||||||
///
|
///
|
||||||
///[screenshotConfiguration] represents the configuration data to use when generating an image from a web view’s contents.
|
///[screenshotConfiguration] represents the configuration data to use when generating an image from a web view’s contents.
|
||||||
///
|
///
|
||||||
///**NOTE for iOS**: available from iOS 11.0+.
|
///**NOTE for iOS**: available on iOS 11.0+.
|
||||||
///
|
///
|
||||||
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkwebview/2873260-takesnapshot
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkwebview/2873260-takesnapshot
|
||||||
Future<Uint8List?> takeScreenshot({ScreenshotConfiguration? screenshotConfiguration}) async {
|
Future<Uint8List?> takeScreenshot({ScreenshotConfiguration? screenshotConfiguration}) async {
|
||||||
|
@ -2088,6 +2088,35 @@ class InAppWebViewController {
|
||||||
return CallAsyncJavaScriptResult(value: data["value"], error: data["error"]);
|
return CallAsyncJavaScriptResult(value: data["value"], error: data["error"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///Saves the current WebView as a web archive.
|
||||||
|
///Returns the file path under which the web archive file was saved, or `null` if saving the file failed.
|
||||||
|
///
|
||||||
|
///[filePath] represents the file path where the archive should be placed. This value cannot be `null`.
|
||||||
|
///
|
||||||
|
///[autoname] if `false`, takes [filePath] to be a file.
|
||||||
|
///If `true`, [filePath] is assumed to be a directory in which a filename will be chosen according to the URL of the current page.
|
||||||
|
///
|
||||||
|
///**NOTE for iOS**: Available on iOS 14.0+. If [autoname] is `false`, the [filePath] must ends with the [WebArchiveFormat.WEBARCHIVE] file extension.
|
||||||
|
///
|
||||||
|
///**NOTE for Android**: if [autoname] is `false`, the [filePath] must ends with the [WebArchiveFormat.MHT] file extension.
|
||||||
|
///
|
||||||
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#saveWebArchive(java.lang.String,%20boolean,%20android.webkit.ValueCallback%3Cjava.lang.String%3E)
|
||||||
|
Future<String?> saveWebArchive(
|
||||||
|
{required String filePath, bool autoname = false}) async {
|
||||||
|
if (!autoname) {
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
assert(filePath.endsWith("." + WebArchiveFormat.MHT.toValue()));
|
||||||
|
} else if (Platform.isIOS) {
|
||||||
|
assert(filePath.endsWith("." + WebArchiveFormat.WEBARCHIVE.toValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
args.putIfAbsent("filePath", () => filePath);
|
||||||
|
args.putIfAbsent("autoname", () => autoname);
|
||||||
|
return await _channel.invokeMethod('saveWebArchive', args);
|
||||||
|
}
|
||||||
|
|
||||||
///Gets the default user agent.
|
///Gets the default user agent.
|
||||||
///
|
///
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebSettings#getDefaultUserAgent(android.content.Context)
|
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebSettings#getDefaultUserAgent(android.content.Context)
|
||||||
|
@ -2180,23 +2209,6 @@ class AndroidInAppWebViewController {
|
||||||
return await _controller._channel.invokeMethod('pageUp', args);
|
return await _controller._channel.invokeMethod('pageUp', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Saves the current WebView as a web archive.
|
|
||||||
///Returns the filename under which the file was saved, or `null` if saving the file failed.
|
|
||||||
///
|
|
||||||
///[basename] the filename where the archive should be placed. This value cannot be `null`.
|
|
||||||
///
|
|
||||||
///[autoname] if `false`, takes basename to be a file.
|
|
||||||
///If `true`, [basename] is assumed to be a directory in which a filename will be chosen according to the URL of the current page.
|
|
||||||
///
|
|
||||||
///**Official Android API**: https://developer.android.com/reference/android/webkit/WebView#saveWebArchive(java.lang.String,%20boolean,%20android.webkit.ValueCallback%3Cjava.lang.String%3E)
|
|
||||||
Future<String?> saveWebArchive(
|
|
||||||
{required String basename, required bool autoname}) async {
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
|
||||||
args.putIfAbsent("basename", () => basename);
|
|
||||||
args.putIfAbsent("autoname", () => autoname);
|
|
||||||
return await _controller._channel.invokeMethod('saveWebArchive', args);
|
|
||||||
}
|
|
||||||
|
|
||||||
///Performs zoom in in this WebView.
|
///Performs zoom in in this WebView.
|
||||||
///Returns `true` if zoom in succeeds, `false` if no zoom changes.
|
///Returns `true` if zoom in succeeds, `false` if no zoom changes.
|
||||||
///
|
///
|
||||||
|
@ -2337,14 +2349,30 @@ class IOSInAppWebViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Generates PDF data from the web view’s contents asynchronously.
|
///Generates PDF data from the web view’s contents asynchronously.
|
||||||
|
///Returns `null` if a problem occurred.
|
||||||
///
|
///
|
||||||
///[iosWKPdfConfiguration] represents the object that specifies the portion of the web view to capture as PDF data.
|
///[iosWKPdfConfiguration] represents the object that specifies the portion of the web view to capture as PDF data.
|
||||||
|
///
|
||||||
|
///**NOTE**: available only on iOS 14.0+.
|
||||||
|
///
|
||||||
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkwebview/3650490-createpdf
|
||||||
Future<Uint8List?> createPdf({IOSWKPDFConfiguration? iosWKPdfConfiguration}) async {
|
Future<Uint8List?> createPdf({IOSWKPDFConfiguration? iosWKPdfConfiguration}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('iosWKPdfConfiguration', () => iosWKPdfConfiguration?.toMap());
|
args.putIfAbsent('iosWKPdfConfiguration', () => iosWKPdfConfiguration?.toMap());
|
||||||
return await _controller._channel.invokeMethod('createPdf', args);
|
return await _controller._channel.invokeMethod('createPdf', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///Creates a web archive of the web view’s current contents asynchronously.
|
||||||
|
///Returns `null` if a problem occurred.
|
||||||
|
///
|
||||||
|
///**NOTE**: available only on iOS 14.0+.
|
||||||
|
///
|
||||||
|
///**Official iOS API**: https://developer.apple.com/documentation/webkit/wkwebview/3650491-createwebarchivedata
|
||||||
|
Future<Uint8List?> createWebArchiveData() async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
return await _controller._channel.invokeMethod('createWebArchiveData', args);
|
||||||
|
}
|
||||||
|
|
||||||
///Returns a Boolean value that indicates whether WebKit natively supports resources with the specified URL scheme.
|
///Returns a Boolean value that indicates whether WebKit natively supports resources with the specified URL scheme.
|
||||||
///
|
///
|
||||||
///[urlScheme] represents the URL scheme associated with the resource.
|
///[urlScheme] represents the URL scheme associated with the resource.
|
||||||
|
|
|
@ -4874,3 +4874,43 @@ class IOSWKPDFConfiguration {
|
||||||
return toMap().toString();
|
return toMap().toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///Class that represents the known Web Archive formats used when saving a web page.
|
||||||
|
class WebArchiveFormat {
|
||||||
|
final String _value;
|
||||||
|
|
||||||
|
const WebArchiveFormat._internal(this._value);
|
||||||
|
|
||||||
|
static final Set<WebArchiveFormat> values = [
|
||||||
|
WebArchiveFormat.MHT,
|
||||||
|
WebArchiveFormat.WEBARCHIVE
|
||||||
|
].toSet();
|
||||||
|
|
||||||
|
static WebArchiveFormat? fromValue(String? value) {
|
||||||
|
if (value != null) {
|
||||||
|
try {
|
||||||
|
return WebArchiveFormat.values.firstWhere(
|
||||||
|
(element) => element.toValue() == value);
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String toValue() => _value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _value;
|
||||||
|
|
||||||
|
///Web Archive format used only by Android.
|
||||||
|
static const MHT = const WebArchiveFormat._internal("mht");
|
||||||
|
|
||||||
|
///Web Archive format used only by iOS.
|
||||||
|
static const WEBARCHIVE = const WebArchiveFormat._internal("webarchive");
|
||||||
|
|
||||||
|
bool operator ==(value) => value == _value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => _value.hashCode;
|
||||||
|
}
|
Loading…
Reference in New Issue