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 `contentWorld` argument to `evaluateJavascript` WebView method
|
||||
- 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 `screenshotConfiguration` optional argument to `takeScreenshot` WebView method
|
||||
- Updated integration tests
|
||||
|
@ -44,6 +44,7 @@
|
|||
- `allowUniversalAccessFromFileURLs` and `allowFileAccessFromFileURLs` WebView options moved from Android-specific options to cross-platform options
|
||||
- Added `callAsyncJavaScript` name to the list of javaScriptHandlerForbiddenNames
|
||||
- Changed `zoomBy` WebView method signature
|
||||
- Moved `saveWebArchive` WebView method from Android-specific to cross-platform
|
||||
|
||||
## 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.
|
||||
|
||||
* `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.
|
||||
* `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.
|
||||
|
|
|
@ -338,9 +338,9 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
|
|||
break;
|
||||
case "saveWebArchive":
|
||||
if (webView != null) {
|
||||
String basename = (String) call.argument("basename");
|
||||
String filePath = (String) call.argument("filePath");
|
||||
boolean autoname = (boolean) call.argument("autoname");
|
||||
webView.saveWebArchive(basename, autoname, new ValueCallback<String>() {
|
||||
webView.saveWebArchive(filePath, autoname, new ValueCallback<String>() {
|
||||
@Override
|
||||
public void onReceiveValue(String 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}/integration_test/integration_test.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",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
|
@ -272,7 +271,6 @@
|
|||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_inappwebview.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}/pdf_viewer_plugin.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher.framework",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSDocumentsFolderUsageDescription</key>
|
||||
<string>InAppWebView requires access to documents folder</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>InAppWebView requires acess to mic.</string>
|
||||
<string>InAppWebView requires access to mic.</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
|
@ -64,7 +66,7 @@
|
|||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>InAppWebView requires acess to cam.</string>
|
||||
<string>InAppWebView requires access to cam.</string>
|
||||
<key>NSLocalNetworkUsageDescription</key>
|
||||
<string>Allow Flutter tools on your computer to connect and debug your application.</string>
|
||||
</dict>
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'dart:io';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
// import 'package:path_provider/path_provider.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import 'main.dart';
|
||||
|
|
|
@ -18,6 +18,7 @@ Future main() async {
|
|||
WidgetsFlutterBinding.ensureInitialized();
|
||||
// await Permission.camera.request();
|
||||
// await Permission.microphone.request();
|
||||
// await Permission.storage.request();
|
||||
if (Platform.isAndroid) {
|
||||
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
|
||||
|
||||
|
|
|
@ -1700,70 +1700,117 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
: currentIndex + steps >= 0
|
||||
}
|
||||
|
||||
@available(iOS 11.0, *)
|
||||
public func takeScreenshot (with: [String: Any?]?, completionHandler: @escaping (_ screenshot: Data?) -> Void) {
|
||||
if #available(iOS 11.0, *) {
|
||||
var snapshotConfiguration: WKSnapshotConfiguration? = nil
|
||||
if let with = with {
|
||||
snapshotConfiguration = WKSnapshotConfiguration()
|
||||
if let rect = with["rect"] as? [String: Double] {
|
||||
snapshotConfiguration!.rect = CGRect(x: rect["x"]!, y: rect["y"]!, width: rect["width"]!, height: rect["height"]!)
|
||||
}
|
||||
if let snapshotWidth = with["snapshotWidth"] as? Double {
|
||||
snapshotConfiguration!.snapshotWidth = NSNumber(value: snapshotWidth)
|
||||
}
|
||||
if #available(iOS 13.0, *), let afterScreenUpdates = with["iosAfterScreenUpdates"] as? Bool {
|
||||
snapshotConfiguration!.afterScreenUpdates = afterScreenUpdates
|
||||
}
|
||||
var snapshotConfiguration: WKSnapshotConfiguration? = nil
|
||||
if let with = with {
|
||||
snapshotConfiguration = WKSnapshotConfiguration()
|
||||
if let rect = with["rect"] as? [String: Double] {
|
||||
snapshotConfiguration!.rect = CGRect(x: rect["x"]!, y: rect["y"]!, width: rect["width"]!, height: rect["height"]!)
|
||||
}
|
||||
takeSnapshot(with: snapshotConfiguration, completionHandler: {(image, error) -> Void in
|
||||
var imageData: Data? = nil
|
||||
if let screenshot = image {
|
||||
if let with = with {
|
||||
switch with["compressFormat"] as! String {
|
||||
case "JPEG":
|
||||
let quality = Float(with["quality"] as! Int) / 100
|
||||
imageData = screenshot.jpegData(compressionQuality: CGFloat(quality))!
|
||||
break
|
||||
case "PNG":
|
||||
imageData = screenshot.pngData()!
|
||||
break
|
||||
default:
|
||||
imageData = screenshot.pngData()!
|
||||
}
|
||||
}
|
||||
else {
|
||||
if let snapshotWidth = with["snapshotWidth"] as? Double {
|
||||
snapshotConfiguration!.snapshotWidth = NSNumber(value: snapshotWidth)
|
||||
}
|
||||
if #available(iOS 13.0, *), let afterScreenUpdates = with["iosAfterScreenUpdates"] as? Bool {
|
||||
snapshotConfiguration!.afterScreenUpdates = afterScreenUpdates
|
||||
}
|
||||
}
|
||||
takeSnapshot(with: snapshotConfiguration, completionHandler: {(image, error) -> Void in
|
||||
var imageData: Data? = nil
|
||||
if let screenshot = image {
|
||||
if let with = with {
|
||||
switch with["compressFormat"] as! String {
|
||||
case "JPEG":
|
||||
let quality = Float(with["quality"] as! Int) / 100
|
||||
imageData = screenshot.jpegData(compressionQuality: CGFloat(quality))!
|
||||
break
|
||||
case "PNG":
|
||||
imageData = screenshot.pngData()!
|
||||
break
|
||||
default:
|
||||
imageData = screenshot.pngData()!
|
||||
}
|
||||
}
|
||||
completionHandler(imageData)
|
||||
})
|
||||
} else {
|
||||
completionHandler(nil)
|
||||
else {
|
||||
imageData = screenshot.pngData()!
|
||||
}
|
||||
}
|
||||
completionHandler(imageData)
|
||||
})
|
||||
}
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
public func createPdf (configuration: [String: Any?]?, completionHandler: @escaping (_ pdf: Data?) -> Void) {
|
||||
let pdfConfiguration: WKPDFConfiguration = .init()
|
||||
if let configuration = configuration {
|
||||
if let rect = configuration["rect"] as? [String: Double] {
|
||||
pdfConfiguration.rect = CGRect(x: rect["x"]!, y: rect["y"]!, width: rect["width"]!, height: rect["height"]!)
|
||||
}
|
||||
}
|
||||
createPDF(configuration: pdfConfiguration) { (result) in
|
||||
switch (result) {
|
||||
case .success(let data):
|
||||
completionHandler(data)
|
||||
return
|
||||
case .failure(let error):
|
||||
print(error.localizedDescription)
|
||||
completionHandler(nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func createPdf (configuration: [String: Any?]?, completionHandler: @escaping (_ pdf: Data?) -> Void) {
|
||||
if #available(iOS 14.0, *) {
|
||||
let pdfConfiguration: WKPDFConfiguration = .init()
|
||||
if let configuration = configuration {
|
||||
if let rect = configuration["rect"] as? [String: Double] {
|
||||
pdfConfiguration.rect = CGRect(x: rect["x"]!, y: rect["y"]!, width: rect["width"]!, height: rect["height"]!)
|
||||
}
|
||||
@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
|
||||
}
|
||||
createPDF(configuration: pdfConfiguration) { (result) in
|
||||
switch (result) {
|
||||
case .success(let data):
|
||||
completionHandler(data)
|
||||
return
|
||||
case .failure(let error):
|
||||
})
|
||||
}
|
||||
|
||||
@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)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
completionHandler(nil)
|
||||
}
|
||||
} else {
|
||||
completionHandler(nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
public func loadUrl(url: URL, headers: [String: String]?) {
|
||||
|
|
|
@ -128,7 +128,7 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
|||
result(webView?.isLoading ?? false)
|
||||
break
|
||||
case "takeScreenshot":
|
||||
if webView != nil {
|
||||
if webView != nil, #available(iOS 11.0, *) {
|
||||
let screenshotConfiguration = arguments!["screenshotConfiguration"] as? [String: Any?]
|
||||
webView!.takeScreenshot(with: screenshotConfiguration, completionHandler: { (screenshot) -> Void in
|
||||
result(screenshot)
|
||||
|
@ -403,7 +403,7 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
|||
}
|
||||
break
|
||||
case "createPdf":
|
||||
if webView != nil {
|
||||
if webView != nil, #available(iOS 14.0, *) {
|
||||
let configuration = arguments!["iosWKPdfConfiguration"] as? [String: Any?]
|
||||
webView!.createPdf(configuration: configuration, completionHandler: { (pdf) -> Void in
|
||||
result(pdf)
|
||||
|
@ -413,6 +413,28 @@ class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
|||
result(nil)
|
||||
}
|
||||
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:
|
||||
result(FlutterMethodNotImplemented)
|
||||
break
|
||||
|
|
|
@ -1508,7 +1508,7 @@ class InAppWebViewController {
|
|||
///
|
||||
///[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
|
||||
Future<Uint8List?> takeScreenshot({ScreenshotConfiguration? screenshotConfiguration}) async {
|
||||
|
@ -2088,6 +2088,35 @@ class InAppWebViewController {
|
|||
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.
|
||||
///
|
||||
///**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);
|
||||
}
|
||||
|
||||
///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.
|
||||
///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.
|
||||
///Returns `null` if a problem occurred.
|
||||
///
|
||||
///[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 {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent('iosWKPdfConfiguration', () => iosWKPdfConfiguration?.toMap());
|
||||
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.
|
||||
///
|
||||
///[urlScheme] represents the URL scheme associated with the resource.
|
||||
|
|
|
@ -4873,4 +4873,44 @@ class IOSWKPDFConfiguration {
|
|||
String 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