implemented WKDownloadDelegate iOS protocol for iOS 14.5
This commit is contained in:
parent
9e6feccbf6
commit
8315b811a8
|
@ -25,6 +25,7 @@ public class NavigationAction {
|
||||||
navigationActionMap.put("navigationType", null);
|
navigationActionMap.put("navigationType", null);
|
||||||
navigationActionMap.put("sourceFrame", null);
|
navigationActionMap.put("sourceFrame", null);
|
||||||
navigationActionMap.put("targetFrame", null);
|
navigationActionMap.put("targetFrame", null);
|
||||||
|
navigationActionMap.put("shouldPerformDownload", null);
|
||||||
return navigationActionMap;
|
return navigationActionMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,10 @@ import Flutter
|
||||||
import Foundation
|
import Foundation
|
||||||
import WebKit
|
import WebKit
|
||||||
|
|
||||||
public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler, UIGestureRecognizerDelegate, PullToRefreshDelegate {
|
public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
|
||||||
|
WKNavigationDelegate, WKScriptMessageHandler, UIGestureRecognizerDelegate,
|
||||||
|
WKDownloadDelegate,
|
||||||
|
PullToRefreshDelegate {
|
||||||
|
|
||||||
var windowId: Int64?
|
var windowId: Int64?
|
||||||
var windowCreated = false
|
var windowCreated = false
|
||||||
|
@ -1517,11 +1520,14 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
var action = response["action"] as? Int
|
var action = response["action"] as? Int
|
||||||
action = action != nil ? action : 0;
|
action = action != nil ? action : 0;
|
||||||
switch action {
|
switch action {
|
||||||
case 1:
|
case 1:
|
||||||
decisionHandler(.grant)
|
decisionHandler(.grant)
|
||||||
break
|
break
|
||||||
default:
|
case 2:
|
||||||
decisionHandler(.deny)
|
decisionHandler(.prompt)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
decisionHandler(.deny)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1555,11 +1561,14 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
var action = response["action"] as? Int
|
var action = response["action"] as? Int
|
||||||
action = action != nil ? action : 0;
|
action = action != nil ? action : 0;
|
||||||
switch action {
|
switch action {
|
||||||
case 1:
|
case 1:
|
||||||
decisionHandler(.grant)
|
decisionHandler(.grant)
|
||||||
break
|
break
|
||||||
default:
|
case 2:
|
||||||
decisionHandler(.deny)
|
decisionHandler(.prompt)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
decisionHandler(.deny)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1578,6 +1587,39 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(iOS 14.5, *)
|
||||||
|
public func download(_ download: WKDownload, decideDestinationUsing response: URLResponse, suggestedFilename: String, completionHandler: @escaping (URL?) -> Void) {
|
||||||
|
if let url = response.url, let useOnDownloadStart = settings?.useOnDownloadStart, useOnDownloadStart {
|
||||||
|
let downloadStartRequest = DownloadStartRequest(url: url.absoluteString,
|
||||||
|
userAgent: nil,
|
||||||
|
contentDisposition: nil,
|
||||||
|
mimeType: response.mimeType,
|
||||||
|
contentLength: response.expectedContentLength,
|
||||||
|
suggestedFilename: suggestedFilename,
|
||||||
|
textEncodingName: response.textEncodingName)
|
||||||
|
onDownloadStartRequest(request: downloadStartRequest)
|
||||||
|
}
|
||||||
|
download.delegate = nil
|
||||||
|
// cancel the download
|
||||||
|
completionHandler(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 14.5, *)
|
||||||
|
public func webView(_ webView: WKWebView, navigationResponse: WKNavigationResponse, didBecome download: WKDownload) {
|
||||||
|
let response = navigationResponse.response
|
||||||
|
if let url = response.url, let useOnDownloadStart = settings?.useOnDownloadStart, useOnDownloadStart {
|
||||||
|
let downloadStartRequest = DownloadStartRequest(url: url.absoluteString,
|
||||||
|
userAgent: nil,
|
||||||
|
contentDisposition: nil,
|
||||||
|
mimeType: response.mimeType,
|
||||||
|
contentLength: response.expectedContentLength,
|
||||||
|
suggestedFilename: response.suggestedFilename,
|
||||||
|
textEncodingName: response.textEncodingName)
|
||||||
|
onDownloadStartRequest(request: downloadStartRequest)
|
||||||
|
}
|
||||||
|
download.delegate = nil
|
||||||
|
}
|
||||||
|
|
||||||
public func webView(_ webView: WKWebView,
|
public func webView(_ webView: WKWebView,
|
||||||
decidePolicyFor navigationAction: WKNavigationAction,
|
decidePolicyFor navigationAction: WKNavigationAction,
|
||||||
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
||||||
|
@ -1587,6 +1629,11 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if #available(iOS 14.5, *), navigationAction.request.url!.absoluteString.hasSuffix(".dat") {
|
||||||
|
decisionHandler(.download)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if navigationAction.request.url != nil {
|
if navigationAction.request.url != nil {
|
||||||
|
|
||||||
if let useShouldOverrideUrlLoading = settings?.useShouldOverrideUrlLoading, useShouldOverrideUrlLoading {
|
if let useShouldOverrideUrlLoading = settings?.useShouldOverrideUrlLoading, useShouldOverrideUrlLoading {
|
||||||
|
@ -1605,7 +1652,8 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
if let r = result {
|
if let r = result {
|
||||||
response = r as! [String: Any]
|
response = r as! [String: Any]
|
||||||
let action = response["action"] as? Int
|
let action = response["action"] as? Int
|
||||||
let navigationActionPolicy = WKNavigationActionPolicy.init(rawValue: action ?? WKNavigationActionPolicy.cancel.rawValue) ??
|
let navigationActionPolicy = WKNavigationActionPolicy
|
||||||
|
.init(rawValue: action ?? WKNavigationActionPolicy.cancel.rawValue) ??
|
||||||
WKNavigationActionPolicy.cancel
|
WKNavigationActionPolicy.cancel
|
||||||
decisionHandler(navigationActionPolicy)
|
decisionHandler(navigationActionPolicy)
|
||||||
return;
|
return;
|
||||||
|
@ -1647,15 +1695,11 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
var response: [String: Any]
|
var response: [String: Any]
|
||||||
if let r = result {
|
if let r = result {
|
||||||
response = r as! [String: Any]
|
response = r as! [String: Any]
|
||||||
var action = response["action"] as? Int
|
let action = response["action"] as? Int
|
||||||
action = action != nil ? action : 0;
|
let navigationActionPolicy = WKNavigationResponsePolicy
|
||||||
switch action {
|
.init(rawValue: action ?? WKNavigationResponsePolicy.cancel.rawValue) ??
|
||||||
case 1:
|
WKNavigationResponsePolicy.cancel
|
||||||
decisionHandler(.allow)
|
decisionHandler(navigationActionPolicy)
|
||||||
break
|
|
||||||
default:
|
|
||||||
decisionHandler(.cancel)
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
decisionHandler(.allow)
|
decisionHandler(.allow)
|
||||||
|
@ -1664,21 +1708,26 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
}
|
}
|
||||||
|
|
||||||
if let useOnDownloadStart = settings?.useOnDownloadStart, useOnDownloadStart {
|
if let useOnDownloadStart = settings?.useOnDownloadStart, useOnDownloadStart {
|
||||||
let mimeType = navigationResponse.response.mimeType
|
if #available(iOS 14.5, *), !navigationResponse.canShowMIMEType {
|
||||||
if let url = navigationResponse.response.url, navigationResponse.isForMainFrame {
|
decisionHandler(.download)
|
||||||
if url.scheme != "file", mimeType != nil, !mimeType!.starts(with: "text/") {
|
return
|
||||||
let downloadStartRequest = DownloadStartRequest(url: url.absoluteString,
|
} else {
|
||||||
userAgent: nil,
|
let mimeType = navigationResponse.response.mimeType
|
||||||
contentDisposition: nil,
|
if let url = navigationResponse.response.url, navigationResponse.isForMainFrame {
|
||||||
mimeType: mimeType,
|
if url.scheme != "file", mimeType != nil, !mimeType!.starts(with: "text/") {
|
||||||
contentLength: navigationResponse.response.expectedContentLength,
|
let downloadStartRequest = DownloadStartRequest(url: url.absoluteString,
|
||||||
suggestedFilename: navigationResponse.response.suggestedFilename,
|
userAgent: nil,
|
||||||
textEncodingName: navigationResponse.response.textEncodingName)
|
contentDisposition: nil,
|
||||||
onDownloadStartRequest(request: downloadStartRequest)
|
mimeType: mimeType,
|
||||||
if useOnNavigationResponse == nil || !useOnNavigationResponse! {
|
contentLength: navigationResponse.response.expectedContentLength,
|
||||||
decisionHandler(.cancel)
|
suggestedFilename: navigationResponse.response.suggestedFilename,
|
||||||
|
textEncodingName: navigationResponse.response.textEncodingName)
|
||||||
|
onDownloadStartRequest(request: downloadStartRequest)
|
||||||
|
if useOnNavigationResponse == nil || !useOnNavigationResponse! {
|
||||||
|
decisionHandler(.cancel)
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,10 @@ import WebKit
|
||||||
|
|
||||||
extension WKNavigationAction {
|
extension WKNavigationAction {
|
||||||
public func toMap () -> [String:Any?] {
|
public func toMap () -> [String:Any?] {
|
||||||
|
var shouldPerformDownload: Bool? = nil
|
||||||
|
if #available(iOS 14.5, *) {
|
||||||
|
shouldPerformDownload = self.shouldPerformDownload
|
||||||
|
}
|
||||||
return [
|
return [
|
||||||
"request": request.toMap(),
|
"request": request.toMap(),
|
||||||
"isForMainFrame": targetFrame?.isMainFrame ?? false,
|
"isForMainFrame": targetFrame?.isMainFrame ?? false,
|
||||||
|
@ -17,7 +21,8 @@ extension WKNavigationAction {
|
||||||
"isRedirect": nil,
|
"isRedirect": nil,
|
||||||
"navigationType": navigationType.rawValue,
|
"navigationType": navigationType.rawValue,
|
||||||
"sourceFrame": sourceFrame.toMap(),
|
"sourceFrame": sourceFrame.toMap(),
|
||||||
"targetFrame": targetFrame?.toMap()
|
"targetFrame": targetFrame?.toMap(),
|
||||||
|
"shouldPerformDownload": shouldPerformDownload
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4717,6 +4717,11 @@ class PermissionResponseAction {
|
||||||
///Grants origin the permission to access the given resources.
|
///Grants origin the permission to access the given resources.
|
||||||
static const GRANT = const PermissionResponseAction._internal(1);
|
static const GRANT = const PermissionResponseAction._internal(1);
|
||||||
|
|
||||||
|
///Prompt the user for permission for the requested resource.
|
||||||
|
///
|
||||||
|
///**NOTE**: available only on iOS 15.0+. It will fallback to [DENY].
|
||||||
|
static const PROMPT = const PermissionResponseAction._internal(2);
|
||||||
|
|
||||||
bool operator ==(value) => value == _value;
|
bool operator ==(value) => value == _value;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -4875,6 +4880,9 @@ class PermissionRequest {
|
||||||
Uri origin;
|
Uri origin;
|
||||||
|
|
||||||
///List of resources the web content wants to access.
|
///List of resources the web content wants to access.
|
||||||
|
///
|
||||||
|
///**NOTE for iOS**: this list will have only 1 element and will be used by the [PermissionResponse.action]
|
||||||
|
///as the resource to consider when applying the corresponding action.
|
||||||
List<PermissionResourceType> resources;
|
List<PermissionResourceType> resources;
|
||||||
|
|
||||||
///The frame that initiates the request in the web view.
|
///The frame that initiates the request in the web view.
|
||||||
|
@ -4925,6 +4933,8 @@ class PermissionRequest {
|
||||||
///Class that represents the response used by the [WebView.onPermissionRequest] event.
|
///Class that represents the response used by the [WebView.onPermissionRequest] event.
|
||||||
class PermissionResponse {
|
class PermissionResponse {
|
||||||
///Resources granted to be accessed by origin.
|
///Resources granted to be accessed by origin.
|
||||||
|
///
|
||||||
|
///**NOTE for iOS**: not used. The [action] taken is based on the [PermissionRequest.resources].
|
||||||
List<PermissionResourceType> resources;
|
List<PermissionResourceType> resources;
|
||||||
|
|
||||||
///Indicate the [PermissionResponseAction] to take in response of a permission request.
|
///Indicate the [PermissionResponseAction] to take in response of a permission request.
|
||||||
|
@ -4993,6 +5003,11 @@ class NavigationActionPolicy {
|
||||||
///Allow the navigation to continue.
|
///Allow the navigation to continue.
|
||||||
static const ALLOW = const NavigationActionPolicy._internal(1);
|
static const ALLOW = const NavigationActionPolicy._internal(1);
|
||||||
|
|
||||||
|
///Turn the navigation into a download.
|
||||||
|
///
|
||||||
|
///**NOTE**: available only on iOS 14.5+. It will fallback to [CANCEL].
|
||||||
|
static const DOWNLOAD = const NavigationActionPolicy._internal(2);
|
||||||
|
|
||||||
bool operator ==(value) => value == _value;
|
bool operator ==(value) => value == _value;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -5761,6 +5776,11 @@ class NavigationAction {
|
||||||
///**NOTE**: available only on iOS.
|
///**NOTE**: available only on iOS.
|
||||||
FrameInfo? targetFrame;
|
FrameInfo? targetFrame;
|
||||||
|
|
||||||
|
///A value indicating whether the web content used a download attribute to indicate that this should be downloaded.
|
||||||
|
///
|
||||||
|
///**NOTE**: available only on iOS.
|
||||||
|
bool? shouldPerformDownload;
|
||||||
|
|
||||||
NavigationAction(
|
NavigationAction(
|
||||||
{required this.request,
|
{required this.request,
|
||||||
required this.isForMainFrame,
|
required this.isForMainFrame,
|
||||||
|
@ -5773,7 +5793,8 @@ class NavigationAction {
|
||||||
@Deprecated("Use sourceFrame instead") this.iosSourceFrame,
|
@Deprecated("Use sourceFrame instead") this.iosSourceFrame,
|
||||||
this.sourceFrame,
|
this.sourceFrame,
|
||||||
@Deprecated("Use targetFrame instead") this.iosTargetFrame,
|
@Deprecated("Use targetFrame instead") this.iosTargetFrame,
|
||||||
this.targetFrame}) {
|
this.targetFrame,
|
||||||
|
this.shouldPerformDownload}) {
|
||||||
// ignore: deprecated_member_use_from_same_package
|
// ignore: deprecated_member_use_from_same_package
|
||||||
this.hasGesture = this.hasGesture ?? this.androidHasGesture;
|
this.hasGesture = this.hasGesture ?? this.androidHasGesture;
|
||||||
// ignore: deprecated_member_use_from_same_package
|
// ignore: deprecated_member_use_from_same_package
|
||||||
|
@ -5818,7 +5839,8 @@ class NavigationAction {
|
||||||
// ignore: deprecated_member_use_from_same_package
|
// ignore: deprecated_member_use_from_same_package
|
||||||
IOSWKFrameInfo.fromMap(map["targetFrame"]?.cast<String, dynamic>()),
|
IOSWKFrameInfo.fromMap(map["targetFrame"]?.cast<String, dynamic>()),
|
||||||
targetFrame:
|
targetFrame:
|
||||||
FrameInfo.fromMap(map["targetFrame"]?.cast<String, dynamic>()));
|
FrameInfo.fromMap(map["targetFrame"]?.cast<String, dynamic>()),
|
||||||
|
shouldPerformDownload: map["shouldPerformDownload"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
|
@ -5847,6 +5869,7 @@ class NavigationAction {
|
||||||
"iosTargetFrame": targetFrame?.toMap() ?? iosTargetFrame?.toMap(),
|
"iosTargetFrame": targetFrame?.toMap() ?? iosTargetFrame?.toMap(),
|
||||||
// ignore: deprecated_member_use_from_same_package
|
// ignore: deprecated_member_use_from_same_package
|
||||||
"targetFrame": targetFrame?.toMap() ?? iosTargetFrame?.toMap(),
|
"targetFrame": targetFrame?.toMap() ?? iosTargetFrame?.toMap(),
|
||||||
|
"shouldPerformDownload": shouldPerformDownload
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8953,6 +8976,11 @@ class NavigationResponseAction {
|
||||||
///Allow the navigation to continue.
|
///Allow the navigation to continue.
|
||||||
static const ALLOW = const NavigationResponseAction._internal(1);
|
static const ALLOW = const NavigationResponseAction._internal(1);
|
||||||
|
|
||||||
|
///Turn the navigation into a download.
|
||||||
|
///
|
||||||
|
///**NOTE**: available only on iOS 14.5+. It will fallback to [CANCEL].
|
||||||
|
static const DOWNLOAD = const NavigationResponseAction._internal(2);
|
||||||
|
|
||||||
bool operator ==(value) => value == _value;
|
bool operator ==(value) => value == _value;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
Loading…
Reference in New Issue