Merge branch 'phamconganh-permisstionIos15+' into develop

This commit is contained in:
Lorenzo Pichilli 2022-04-21 13:33:41 +02:00
commit 3ef7d1949d
7 changed files with 149 additions and 10 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
} }
@ -1484,6 +1487,83 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
return result; return result;
} }
@available(iOS 15.0, *)
@available(macOS 12.0, *)
@available(macCatalyst 15.0, *)
public func webView(_ webView: WKWebView,
requestMediaCapturePermissionFor origin: WKSecurityOrigin,
initiatedByFrame frame: WKFrameInfo,
type: WKMediaCaptureType,
decisionHandler: @escaping (WKPermissionDecision) -> Void) {
let origin = "\(origin.protocol)://\(origin.host)\(origin.port != 0 ? ":" + String(origin.port) : "")"
let permissionRequest = PermissionRequest(origin: origin, resources: [type.rawValue], 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 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,
@ -2426,6 +2506,10 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
channel?.invokeMethod("onNavigationResponse", arguments: navigationResponse.toMap(), result: result) channel?.invokeMethod("onNavigationResponse", arguments: navigationResponse.toMap(), result: result)
} }
public func onPermissionRequest(request: PermissionRequest, result: FlutterResult?) {
channel?.invokeMethod("onPermissionRequest", arguments: request.toMap(), result: result)
}
public func onReceivedHttpAuthRequest(challenge: URLAuthenticationChallenge, result: FlutterResult?) { public func onReceivedHttpAuthRequest(challenge: URLAuthenticationChallenge, result: FlutterResult?) {
channel?.invokeMethod("onReceivedHttpAuthRequest", channel?.invokeMethod("onReceivedHttpAuthRequest",
arguments: HttpAuthenticationChallenge(fromChallenge: challenge).toMap(), result: result) arguments: HttpAuthenticationChallenge(fromChallenge: challenge).toMap(), result: result)

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() {