Added support for onPermissionRequest event on iOS 15.0+

This commit is contained in:
Lorenzo Pichilli 2022-04-21 13:33:07 +02:00
parent 09edc2890b
commit f265063a37
7 changed files with 142 additions and 59 deletions

View File

@ -3,6 +3,7 @@
- Deprecated old classes/properties/methods to make them eventually compatible with other operating systems and WebView engines. - Deprecated old classes/properties/methods to make them eventually compatible with other operating systems and WebView engines.
- Added `pauseAllMediaPlayback`, `setAllMediaPlaybackSuspended`, `closeAllMediaPresentations`, `requestMediaPlaybackState` WebView controller methods - Added `pauseAllMediaPlayback`, `setAllMediaPlaybackSuspended`, `closeAllMediaPresentations`, `requestMediaPlaybackState` WebView controller methods
- Added `underPageBackgroundColor`, `isTextInteractionEnabled`, `isSiteSpecificQuirksModeEnabled`, `upgradeKnownHostsToHTTPS` WebView settings - Added `underPageBackgroundColor`, `isTextInteractionEnabled`, `isSiteSpecificQuirksModeEnabled`, `upgradeKnownHostsToHTTPS` WebView settings
- Added support for `onPermissionRequest` event on iOS 15.0+
- Updated `getMetaThemeColor` on iOS 15.0+ - Updated `getMetaThemeColor` on iOS 15.0+
## 5.4.0+2 ## 5.4.0+2

View File

@ -132,10 +132,10 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
urlController.text = this.url; urlController.text = this.url;
}); });
}, },
onPermissionRequest: (controller, origin, resources) async { onPermissionRequest: (controller, request) async {
return PermissionRequestResponse( return PermissionResponse(
resources: resources, resources: request.resources,
action: PermissionRequestResponseAction.GRANT); action: PermissionResponseAction.GRANT);
}, },
shouldOverrideUrlLoading: (controller, navigationAction) async { shouldOverrideUrlLoading: (controller, navigationAction) async {
var uri = navigationAction.request.url!; var uri = navigationAction.request.url!;

View File

@ -433,7 +433,9 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
} }
if #available(iOS 15.0, *) { if #available(iOS 15.0, *) {
configuration.preferences.isSiteSpecificQuirksModeEnabled = settings.isSiteSpecificQuirksModeEnabled if (configuration.preferences.responds(to: #selector(getter: InAppWebViewSettings.isSiteSpecificQuirksModeEnabled))) {
configuration.preferences.isSiteSpecificQuirksModeEnabled = settings.isSiteSpecificQuirksModeEnabled
}
} }
} }
} }
@ -1130,7 +1132,8 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
let underPageBackgroundColor = newSettings.underPageBackgroundColor, !underPageBackgroundColor.isEmpty { let underPageBackgroundColor = newSettings.underPageBackgroundColor, !underPageBackgroundColor.isEmpty {
self.underPageBackgroundColor = UIColor(hexString: underPageBackgroundColor) self.underPageBackgroundColor = UIColor(hexString: underPageBackgroundColor)
} }
if newSettingsMap["isSiteSpecificQuirksModeEnabled"] != nil && if configuration.preferences.responds(to: #selector(getter: InAppWebViewSettings.isSiteSpecificQuirksModeEnabled)),
newSettingsMap["isSiteSpecificQuirksModeEnabled"] != nil &&
settings?.isSiteSpecificQuirksModeEnabled != newSettings.isSiteSpecificQuirksModeEnabled { settings?.isSiteSpecificQuirksModeEnabled != newSettings.isSiteSpecificQuirksModeEnabled {
configuration.preferences.isSiteSpecificQuirksModeEnabled = newSettings.isSiteSpecificQuirksModeEnabled configuration.preferences.isSiteSpecificQuirksModeEnabled = newSettings.isSiteSpecificQuirksModeEnabled
} }
@ -1489,38 +1492,78 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
@available(macOS 12.0, *) @available(macOS 12.0, *)
@available(macCatalyst 15.0, *) @available(macCatalyst 15.0, *)
public func webView(_ webView: WKWebView, public func webView(_ webView: WKWebView,
requestMediaCapturePermissionFor origin: WKSecurityOrigin, requestMediaCapturePermissionFor origin: WKSecurityOrigin,
initiatedByFrame frame: WKFrameInfo, initiatedByFrame frame: WKFrameInfo,
type: WKMediaCaptureType, type: WKMediaCaptureType,
decisionHandler: @escaping (WKPermissionDecision) -> Void) { decisionHandler: @escaping (WKPermissionDecision) -> Void) {
onPermissionRequest(origin: origin, type: type, result: {(result) -> Void in let origin = "\(origin.protocol)://\(origin.host)\(origin.port != 0 ? ":" + String(origin.port) : "")"
if result is FlutterError { let permissionRequest = PermissionRequest(origin: origin, resources: [type.rawValue], frame: frame)
print((result as! FlutterError).message ?? "")
decisionHandler(.deny) onPermissionRequest(request: permissionRequest, result: {(result) -> Void in
} if result is FlutterError {
else if (result as? NSObject) == FlutterMethodNotImplemented { print((result as! FlutterError).message ?? "")
decisionHandler(.deny) decisionHandler(.deny)
} }
else { else if (result as? NSObject) == FlutterMethodNotImplemented {
var response: [String: Any] decisionHandler(.deny)
if let r = result { }
response = r as! [String: Any] else {
var action = response["action"] as? Int var response: [String: Any]
action = action != nil ? action : 0; if let r = result {
// var resources = response["resources"] as? [String] response = r as! [String: Any]
switch action { var action = response["action"] as? Int
case 1: action = action != nil ? action : 0;
decisionHandler(.grant) switch action {
break case 1:
default: decisionHandler(.grant)
decisionHandler(.deny) break
} default:
return; decisionHandler(.deny)
} }
decisionHandler(.deny) return;
} }
}) decisionHandler(.deny)
} }
})
}
@available(iOS 15.0, *)
@available(macOS 12.0, *)
@available(macCatalyst 15.0, *)
public func webView(_ webView: WKWebView,
requestDeviceOrientationAndMotionPermissionFor origin: WKSecurityOrigin,
initiatedByFrame frame: WKFrameInfo,
decisionHandler: @escaping (WKPermissionDecision) -> Void) {
let origin = "\(origin.protocol)://\(origin.host)\(origin.port != 0 ? ":" + String(origin.port) : "")"
let permissionRequest = PermissionRequest(origin: origin, resources: ["deviceOrientationAndMotion"], frame: frame)
onPermissionRequest(request: permissionRequest, result: {(result) -> Void in
if result is FlutterError {
print((result as! FlutterError).message ?? "")
decisionHandler(.deny)
}
else if (result as? NSObject) == FlutterMethodNotImplemented {
decisionHandler(.deny)
}
else {
var response: [String: Any]
if let r = result {
response = r as! [String: Any]
var action = response["action"] as? Int
action = action != nil ? action : 0;
switch action {
case 1:
decisionHandler(.grant)
break
default:
decisionHandler(.deny)
}
return;
}
decisionHandler(.deny)
}
})
}
@available(iOS 13.0, *) @available(iOS 13.0, *)
public func webView(_ webView: WKWebView, public func webView(_ webView: WKWebView,
@ -2463,23 +2506,8 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
channel?.invokeMethod("onNavigationResponse", arguments: navigationResponse.toMap(), result: result) channel?.invokeMethod("onNavigationResponse", arguments: navigationResponse.toMap(), result: result)
} }
@available(iOS 15.0, *) public func onPermissionRequest(request: PermissionRequest, result: FlutterResult?) {
@available(macOS 12.0, *) channel?.invokeMethod("onPermissionRequest", arguments: request.toMap(), result: result)
@available(macCatalyst 15.0, *)
public func onPermissionRequest(origin: WKSecurityOrigin, type: WKMediaCaptureType, result: FlutterResult?) {
let resources: [String];
switch type {
case .camera:
resources = ["camera"]
break;
case .microphone:
resources = ["microphone"]
break;
default:
resources = ["cameraAndMicrophone"]
}
let arguments: [String: Any] = ["origin": origin.protocol + "://" + origin.host, "resources": resources]
channel?.invokeMethod("onPermissionRequest", arguments: arguments, result: result)
} }
public func onReceivedHttpAuthRequest(challenge: URLAuthenticationChallenge, result: FlutterResult?) { public func onReceivedHttpAuthRequest(challenge: URLAuthenticationChallenge, result: FlutterResult?) {

View File

@ -143,7 +143,9 @@ public class InAppWebViewSettings: IWebViewSettings<InAppWebView> {
} }
if #available(iOS 15.0, *) { if #available(iOS 15.0, *) {
realSettings["underPageBackgroundColor"] = webView.underPageBackgroundColor.hexString realSettings["underPageBackgroundColor"] = webView.underPageBackgroundColor.hexString
realSettings["isSiteSpecificQuirksModeEnabled"] = configuration.preferences.isSiteSpecificQuirksModeEnabled if configuration.preferences.responds(to: #selector(getter: self.isSiteSpecificQuirksModeEnabled)) {
realSettings["isSiteSpecificQuirksModeEnabled"] = configuration.preferences.isSiteSpecificQuirksModeEnabled
}
} }
} }
return realSettings return realSettings

View File

@ -0,0 +1,29 @@
//
// PermissionRequest.swift
// flutter_inappwebview
//
// Created by Lorenzo Pichilli on 21/04/22.
//
import Foundation
import WebKit
public class PermissionRequest: NSObject {
var origin: String
var resources: [StringOrInt]
var frame: WKFrameInfo
public init(origin: String, resources: [StringOrInt], frame: WKFrameInfo) {
self.origin = origin
self.resources = resources
self.frame = frame
}
public func toMap () -> [String:Any?] {
return [
"origin": origin,
"resources": resources,
"frame": frame.toMap()
]
}
}

View File

@ -0,0 +1,13 @@
//
// StringOrInt.swift
// flutter_inappwebview
//
// Created by Lorenzo Pichilli on 21/04/22.
//
import Foundation
public protocol StringOrInt { }
extension Int: StringOrInt { }
extension String: StringOrInt { }

View File

@ -4756,6 +4756,10 @@ class PermissionResourceType {
PermissionResourceType.RESOURCE_MIDI_SYSEX, PermissionResourceType.RESOURCE_MIDI_SYSEX,
PermissionResourceType.RESOURCE_PROTECTED_MEDIA_ID, PermissionResourceType.RESOURCE_PROTECTED_MEDIA_ID,
PermissionResourceType.RESOURCE_VIDEO_CAPTURE, PermissionResourceType.RESOURCE_VIDEO_CAPTURE,
PermissionResourceType.CAMERA,
PermissionResourceType.MICROPHONE,
PermissionResourceType.CAMERA_AND_MICROPHONE,
PermissionResourceType.DEVICE_ORIENTATION_AND_MOTION,
].toSet(); ].toSet();
static final Set<PermissionResourceType> _androidValues = [ static final Set<PermissionResourceType> _androidValues = [
@ -4766,7 +4770,10 @@ class PermissionResourceType {
].toSet(); ].toSet();
static final Set<PermissionResourceType> _appleValues = <PermissionResourceType>[ static final Set<PermissionResourceType> _appleValues = <PermissionResourceType>[
PermissionResourceType.CAMERA,
PermissionResourceType.MICROPHONE,
PermissionResourceType.CAMERA_AND_MICROPHONE,
PermissionResourceType.DEVICE_ORIENTATION_AND_MOTION,
].toSet(); ].toSet();
static PermissionResourceType? fromValue(dynamic? value) { static PermissionResourceType? fromValue(dynamic? value) {
@ -4903,7 +4910,7 @@ class PermissionRequest {
return { return {
"origin": origin.toString(), "origin": origin.toString(),
"resources": resources.map((e) => e.toValue()).toList(), "resources": resources.map((e) => e.toValue()).toList(),
"initiatedByFrame": frame?.toMap() "frame": frame?.toMap()
}; };
} }
@ -4930,7 +4937,10 @@ class PermissionResponse {
this.action = PermissionResponseAction.DENY}); this.action = PermissionResponseAction.DENY});
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
return {"resources": resources, "action": action?.toValue()}; return {
"resources": resources.map((e) => e.toValue()).toList(),
"action": action?.toValue()
};
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {