fix #1640, fix #1632, Fixed InAppBrowser.show() possible crash on macOS, Fixed missing windowTitlebarSeparatorStyle, windowAlphaValue, windowStyleMask, windowFrame macOS settings updates when using setSettings()

This commit is contained in:
Lorenzo Pichilli 2023-05-16 20:06:53 +02:00
parent c1db0d1c17
commit b6725128a8
43 changed files with 426 additions and 485 deletions

View File

@ -5,6 +5,9 @@
- Merged "Fix AndroidX migration URL in README.md" [#1529](https://github.com/pichillilorenzo/flutter_inappwebview/pull/1529) (thanks to [cslee](https://github.com/cslee))
- Merged "InAppBrowser Bugfix/viewgroup index crash" [#1618](https://github.com/pichillilorenzo/flutter_inappwebview/pull/1618) (thanks to [KhatibFX](https://github.com/KhatibFX))
- Fixed old iOS versions crash "dyld: Library not loaded: /usr/lib/swift/libswiftCoreGraphics.dylib Reason: image not found" (thanks to [guide-flutter](https://github.com/guide-flutter))
- Fixed `InAppBrowser.show()` possible crash on macOS
- Fixed missing `windowTitlebarSeparatorStyle`, `windowAlphaValue`, `windowStyleMask`, `windowFrame` macOS settings updates when using `setSettings()`
- Fixed "iOS and macOS flutter multiple engine" [#1632](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1632)
## 6.0.0-beta.23

View File

@ -51,7 +51,7 @@ Send a submission request to the [Submit App](https://inappwebview.dev/submit-ap
- Flutter: ">=3.0.0"
- Android: `minSdkVersion 19` and add support for `androidx` (see [AndroidX Migration](https://docs.flutter.dev/development/platform-integration/android/androidx-migration) to migrate an existing app)
- iOS 9.0+: `--ios-language swift`, Xcode version `>= 14.3`
- MacOS 10.11+: Xcode version `>= 14`
- MacOS 10.11+: Xcode version `>= 14.3`
## Installation

View File

@ -9,13 +9,12 @@ import Foundation
public class CredentialDatabase: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_credential_database"
static var registrar: FlutterPluginRegistrar?
static var credentialStore: URLCredentialStorage?
var plugin: SwiftFlutterPlugin?
static var credentialStore = URLCredentialStorage.shared
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: CredentialDatabase.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger()))
CredentialDatabase.registrar = registrar
CredentialDatabase.credentialStore = URLCredentialStorage.shared
init(plugin: SwiftFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: CredentialDatabase.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger()))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -23,11 +22,7 @@ public class CredentialDatabase: ChannelDelegate {
switch call.method {
case "getAllAuthCredentials":
var allCredentials: [[String: Any?]] = []
guard let credentialStore = CredentialDatabase.credentialStore else {
result(allCredentials)
return
}
for (protectionSpace, credentials) in credentialStore.allCredentials {
for (protectionSpace, credentials) in CredentialDatabase.credentialStore.allCredentials {
var crendentials: [[String: Any?]] = []
for c in credentials {
let credential: [String: Any?] = c.value.toMap()
@ -45,10 +40,6 @@ public class CredentialDatabase: ChannelDelegate {
break
case "getHttpAuthCredentials":
var crendentials: [[String: Any?]] = []
guard let credentialStore = CredentialDatabase.credentialStore else {
result(crendentials)
return
}
let host = arguments!["host"] as! String
let urlProtocol = arguments!["protocol"] as? String
@ -58,7 +49,7 @@ public class CredentialDatabase: ChannelDelegate {
realm = nil
}
for (protectionSpace, credentials) in credentialStore.allCredentials {
for (protectionSpace, credentials) in CredentialDatabase.credentialStore.allCredentials {
if protectionSpace.host == host && protectionSpace.realm == realm &&
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
for c in credentials {
@ -70,11 +61,6 @@ public class CredentialDatabase: ChannelDelegate {
result(crendentials)
break
case "setHttpAuthCredential":
guard let credentialStore = CredentialDatabase.credentialStore else {
result(false)
return
}
let host = arguments!["host"] as! String
let urlProtocol = arguments!["protocol"] as? String
let urlPort = arguments!["port"] as? Int ?? 0
@ -85,17 +71,12 @@ public class CredentialDatabase: ChannelDelegate {
let username = arguments!["username"] as! String
let password = arguments!["password"] as! String
let credential = URLCredential(user: username, password: password, persistence: .permanent)
credentialStore.set(credential,
CredentialDatabase.credentialStore.set(credential,
for: URLProtectionSpace(host: host, port: urlPort, protocol: urlProtocol,
realm: realm, authenticationMethod: NSURLAuthenticationMethodHTTPBasic))
result(true)
break
case "removeHttpAuthCredential":
guard let credentialStore = CredentialDatabase.credentialStore else {
result(false)
return
}
let host = arguments!["host"] as! String
let urlProtocol = arguments!["protocol"] as? String
let urlPort = arguments!["port"] as? Int ?? 0
@ -109,7 +90,7 @@ public class CredentialDatabase: ChannelDelegate {
var credential: URLCredential? = nil;
var protectionSpaceCredential: URLProtectionSpace? = nil
for (protectionSpace, credentials) in credentialStore.allCredentials {
for (protectionSpace, credentials) in CredentialDatabase.credentialStore.allCredentials {
if protectionSpace.host == host && protectionSpace.realm == realm &&
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
for c in credentials {
@ -126,17 +107,12 @@ public class CredentialDatabase: ChannelDelegate {
}
if let c = credential, let protectionSpace = protectionSpaceCredential {
credentialStore.remove(c, for: protectionSpace)
CredentialDatabase.credentialStore.remove(c, for: protectionSpace)
}
result(true)
break
case "removeHttpAuthCredentials":
guard let credentialStore = CredentialDatabase.credentialStore else {
result(false)
return
}
let host = arguments!["host"] as! String
let urlProtocol = arguments!["protocol"] as? String
let urlPort = arguments!["port"] as? Int ?? 0
@ -148,7 +124,7 @@ public class CredentialDatabase: ChannelDelegate {
var credentialsToRemove: [URLCredential] = [];
var protectionSpaceCredential: URLProtectionSpace? = nil
for (protectionSpace, credentials) in credentialStore.allCredentials {
for (protectionSpace, credentials) in CredentialDatabase.credentialStore.allCredentials {
if protectionSpace.host == host && protectionSpace.realm == realm &&
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
protectionSpaceCredential = protectionSpace
@ -163,21 +139,16 @@ public class CredentialDatabase: ChannelDelegate {
if let protectionSpace = protectionSpaceCredential {
for credential in credentialsToRemove {
credentialStore.remove(credential, for: protectionSpace)
CredentialDatabase.credentialStore.remove(credential, for: protectionSpace)
}
}
result(true)
break
case "clearAllAuthCredentials":
guard let credentialStore = CredentialDatabase.credentialStore else {
result(false)
return
}
for (protectionSpace, credentials) in credentialStore.allCredentials {
for (protectionSpace, credentials) in CredentialDatabase.credentialStore.allCredentials {
for credential in credentials {
credentialStore.remove(credential.value, for: protectionSpace)
CredentialDatabase.credentialStore.remove(credential.value, for: protectionSpace)
}
}
result(true)
@ -190,8 +161,7 @@ public class CredentialDatabase: ChannelDelegate {
public override func dispose() {
super.dispose()
CredentialDatabase.registrar = nil
CredentialDatabase.credentialStore = nil
plugin = nil
}
deinit {

View File

@ -12,12 +12,14 @@ public class HeadlessInAppWebView : Disposable {
var id: String
var channelDelegate: HeadlessWebViewChannelDelegate?
var flutterWebView: FlutterWebViewController?
var plugin: SwiftFlutterPlugin?
public init(id: String, flutterWebView: FlutterWebViewController) {
public init(plugin: SwiftFlutterPlugin, id: String, flutterWebView: FlutterWebViewController) {
self.id = id
self.flutterWebView = flutterWebView
self.plugin = plugin
let channel = FlutterMethodChannel(name: HeadlessInAppWebView.METHOD_CHANNEL_NAME_PREFIX + id,
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
binaryMessenger: plugin.registrar!.messenger())
self.channelDelegate = HeadlessWebViewChannelDelegate(headlessWebView: self, channel: channel)
}
@ -79,6 +81,7 @@ public class HeadlessInAppWebView : Disposable {
channelDelegate = nil
HeadlessInAppWebViewManager.webViews[id] = nil
flutterWebView = nil
plugin = nil
}
deinit {

View File

@ -15,12 +15,12 @@ import AVFoundation
public class HeadlessInAppWebViewManager: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_headless_inappwebview"
static var registrar: FlutterPluginRegistrar?
var plugin: SwiftFlutterPlugin?
static var webViews: [String: HeadlessInAppWebView?] = [:]
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: HeadlessInAppWebViewManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger()))
HeadlessInAppWebViewManager.registrar = registrar
init(plugin: SwiftFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: HeadlessInAppWebViewManager.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger()))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -30,7 +30,7 @@ public class HeadlessInAppWebViewManager: ChannelDelegate {
switch call.method {
case "run":
let params = arguments!["params"] as! [String: Any?]
HeadlessInAppWebViewManager.run(id: id, params: params)
run(id: id, params: params)
result(true)
break
default:
@ -39,12 +39,15 @@ public class HeadlessInAppWebViewManager: ChannelDelegate {
}
}
public static func run(id: String, params: [String: Any?]) {
let flutterWebView = FlutterWebViewController(registrar: HeadlessInAppWebViewManager.registrar!,
public func run(id: String, params: [String: Any?]) {
guard let plugin = plugin, let registrar = plugin.registrar else {
return
}
let flutterWebView = FlutterWebViewController(registrar: registrar,
withFrame: CGRect.zero,
viewIdentifier: id,
params: params as NSDictionary)
let headlessInAppWebView = HeadlessInAppWebView(id: id, flutterWebView: flutterWebView)
let headlessInAppWebView = HeadlessInAppWebView(plugin: plugin, id: id, flutterWebView: flutterWebView)
HeadlessInAppWebViewManager.webViews[id] = headlessInAppWebView
headlessInAppWebView.prepare(params: params as NSDictionary)
@ -54,12 +57,12 @@ public class HeadlessInAppWebViewManager: ChannelDelegate {
public override func dispose() {
super.dispose()
HeadlessInAppWebViewManager.registrar = nil
let headlessWebViews = HeadlessInAppWebViewManager.webViews.values
headlessWebViews.forEach { (headlessWebView: HeadlessInAppWebView?) in
headlessWebView?.dispose()
}
HeadlessInAppWebViewManager.webViews.removeAll()
plugin = nil
}
deinit {

View File

@ -16,13 +16,13 @@ public class InAppBrowserManager: ChannelDelegate {
static let WEBVIEW_STORYBOARD = "WebView"
static let WEBVIEW_STORYBOARD_CONTROLLER_ID = "viewController"
static let NAV_STORYBOARD_CONTROLLER_ID = "navController"
static var registrar: FlutterPluginRegistrar?
var plugin: SwiftFlutterPlugin?
private var previousStatusBarStyle = -1
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: InAppBrowserManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger()))
InAppBrowserManager.registrar = registrar
init(plugin: SwiftFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: InAppBrowserManager.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger()))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -55,6 +55,7 @@ public class InAppBrowserManager: ChannelDelegate {
let _ = webViewSettings.parse(settings: settings)
let webViewController = InAppBrowserWebViewController()
webViewController.plugin = plugin
webViewController.browserSettings = browserSettings
webViewController.isHidden = browserSettings.hidden
webViewController.webViewSettings = webViewSettings
@ -137,7 +138,7 @@ public class InAppBrowserManager: ChannelDelegate {
public override func dispose() {
super.dispose()
InAppBrowserManager.registrar = nil
plugin = nil
}
deinit {

View File

@ -23,6 +23,7 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
var tmpWindow: UIWindow?
var id: String = ""
var plugin: SwiftFlutterPlugin?
var windowId: Int64?
var webView: InAppWebView?
var channelDelegate: InAppBrowserChannelDelegate?
@ -41,7 +42,11 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
var isHidden = false
public override func loadView() {
let channel = FlutterMethodChannel(name: InAppBrowserWebViewController.METHOD_CHANNEL_NAME_PREFIX + id, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
guard let registrar = plugin?.registrar else {
return
}
let channel = FlutterMethodChannel(name: InAppBrowserWebViewController.METHOD_CHANNEL_NAME_PREFIX + id, binaryMessenger: registrar.messenger())
channelDelegate = InAppBrowserChannelDelegate(channel: channel)
var userScripts: [UserScript] = []
@ -73,13 +78,13 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
let pullToRefreshSettings = PullToRefreshSettings()
let _ = pullToRefreshSettings.parse(settings: pullToRefreshInitialSettings)
let pullToRefreshControl = PullToRefreshControl(registrar: SwiftFlutterPlugin.instance!.registrar!, id: id, settings: pullToRefreshSettings)
let pullToRefreshControl = PullToRefreshControl(registrar: registrar, id: id, settings: pullToRefreshSettings)
webView.pullToRefreshControl = pullToRefreshControl
pullToRefreshControl.delegate = webView
pullToRefreshControl.prepare()
let findInteractionController = FindInteractionController(
registrar: SwiftFlutterPlugin.instance!.registrar!,
registrar: registrar,
id: id, webView: webView, settings: nil)
webView.findInteractionController = findInteractionController
findInteractionController.prepare()
@ -578,6 +583,7 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
backButton.target = nil
reloadButton.target = nil
shareButton.target = nil
plugin = nil
}
deinit {

View File

@ -63,7 +63,7 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView, Disposable
pullToRefreshControl.prepare()
let findInteractionController = FindInteractionController(
registrar: SwiftFlutterPlugin.instance!.registrar!,
registrar: registrar,
id: viewId, webView: webView!, settings: nil)
webView!.findInteractionController = findInteractionController
findInteractionController.prepare()

View File

@ -17,6 +17,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
static var METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_"
var id: Any? // viewId
var registrar: FlutterPluginRegistrar?
var windowId: Int64?
var windowCreated = false
var inAppBrowserDelegate: InAppBrowserDelegate?
@ -71,6 +72,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
contextMenu: [String: Any]?, userScripts: [UserScript] = []) {
super.init(frame: frame, configuration: configuration)
self.id = id
self.registrar = registrar
if let id = id, let registrar = registrar {
let channel = FlutterMethodChannel(name: InAppWebView.METHOD_CHANNEL_NAME_PREFIX + String(describing: id),
binaryMessenger: registrar.messenger())
@ -938,9 +940,11 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
}
public func loadFile(assetFilePath: String) throws {
let assetURL = try Util.getUrlAsset(assetFilePath: assetFilePath)
let urlRequest = URLRequest(url: assetURL)
loadUrl(urlRequest: urlRequest, allowingReadAccessTo: nil)
if let registrar = registrar {
let assetURL = try Util.getUrlAsset(registrar: registrar, assetFilePath: assetFilePath)
let urlRequest = URLRequest(url: assetURL)
loadUrl(urlRequest: urlRequest, allowingReadAccessTo: nil)
}
}
func setSettings(newSettings: InAppWebViewSettings, newSettingsMap: [String: Any]) {
@ -1973,8 +1977,8 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
completionHandler(.useCredential, credential)
break
case 2:
if InAppWebView.credentialsProposed.count == 0, let credentialStore = CredentialDatabase.credentialStore {
for (protectionSpace, credentials) in credentialStore.allCredentials {
if InAppWebView.credentialsProposed.count == 0 {
for (protectionSpace, credentials) in CredentialDatabase.credentialStore.allCredentials {
if protectionSpace.host == host && protectionSpace.realm == realm &&
protectionSpace.protocol == prot && protectionSpace.port == port {
for credential in credentials {
@ -2086,7 +2090,9 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
var path: String = certificatePath
do {
path = try Util.getAbsPathAsset(assetFilePath: certificatePath)
if let registrar = self.registrar {
path = try Util.getAbsPathAsset(registrar: registrar, assetFilePath: certificatePath)
}
} catch {}
if let PKCS12Data = NSData(contentsOfFile: path),
@ -2973,8 +2979,8 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
}
let animated = settings?.animated ?? true
if let id = printJobId {
let printJob = PrintJobController(id: id, job: printController, settings: settings)
if let id = printJobId, let registrar = registrar {
let printJob = PrintJobController(registrar: registrar, id: id, job: printController, settings: settings)
PrintJobManager.jobs[id] = printJob
printJob.present(animated: animated, completionHandler: completionHandler)
} else {
@ -3116,9 +3122,13 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
}
}
public func createWebMessageChannel(completionHandler: ((WebMessageChannel) -> Void)? = nil) -> WebMessageChannel {
public func createWebMessageChannel(completionHandler: ((WebMessageChannel?) -> Void)? = nil) -> WebMessageChannel? {
guard let registrar = registrar else {
completionHandler?(nil)
return nil
}
let id = NSUUID().uuidString
let webMessageChannel = WebMessageChannel(id: id)
let webMessageChannel = WebMessageChannel(registrar: registrar, id: id)
webMessageChannel.initJsInstance(webView: self, completionHandler: completionHandler)
webMessageChannels[id] = webMessageChannel
@ -3235,6 +3245,7 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
SharedLastTouchPointTimestamp.removeValue(forKey: self)
callAsyncJavaScriptBelowIOS14Results.removeAll()
super.removeFromSuperview()
registrar = nil
}
deinit {

View File

@ -13,12 +13,14 @@ public class WebMessageChannel : FlutterMethodCallDelegate {
var channelDelegate: WebMessageChannelChannelDelegate?
weak var webView: InAppWebView?
var ports: [WebMessagePort] = []
var registrar: FlutterPluginRegistrar?
public init(id: String) {
public init(registrar: FlutterPluginRegistrar, id: String) {
self.id = id
self.registrar = registrar
super.init()
let channel = FlutterMethodChannel(name: WebMessageChannel.METHOD_CHANNEL_NAME_PREFIX + id,
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
binaryMessenger: registrar.messenger())
self.channelDelegate = WebMessageChannelChannelDelegate(webMessageChannel: self, channel: channel)
self.ports = [
WebMessagePort(name: "port1", webMessageChannel: self),
@ -26,7 +28,7 @@ public class WebMessageChannel : FlutterMethodCallDelegate {
]
}
public func initJsInstance(webView: InAppWebView, completionHandler: ((WebMessageChannel) -> Void)? = nil) {
public func initJsInstance(webView: InAppWebView, completionHandler: ((WebMessageChannel?) -> Void)? = nil) {
self.webView = webView
if let webView = self.webView {
webView.evaluateJavascript(source: """
@ -37,7 +39,7 @@ public class WebMessageChannel : FlutterMethodCallDelegate {
completionHandler?(self)
}
} else {
completionHandler?(self)
completionHandler?(nil)
}
}
@ -65,6 +67,7 @@ public class WebMessageChannel : FlutterMethodCallDelegate {
})();
""")
webView = nil
registrar = nil
}
deinit {

View File

@ -15,14 +15,16 @@ public class WebMessageListener : FlutterMethodCallDelegate {
var allowedOriginRules: Set<String>
var channelDelegate: WebMessageListenerChannelDelegate?
weak var webView: InAppWebView?
var registrar: FlutterPluginRegistrar?
public init(id: String, jsObjectName: String, allowedOriginRules: Set<String>) {
public init(registrar: FlutterPluginRegistrar, id: String, jsObjectName: String, allowedOriginRules: Set<String>) {
self.id = id
self.registrar = registrar
self.jsObjectName = jsObjectName
self.allowedOriginRules = allowedOriginRules
super.init()
let channel = FlutterMethodChannel(name: WebMessageListener.METHOD_CHANNEL_NAME_PREFIX + self.id + "_" + self.jsObjectName,
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
binaryMessenger: registrar.messenger())
self.channelDelegate = WebMessageListenerChannelDelegate(webMessageListener: self, channel: channel)
}
@ -114,11 +116,12 @@ public class WebMessageListener : FlutterMethodCallDelegate {
}
}
public static func fromMap(map: [String:Any?]?) -> WebMessageListener? {
public static func fromMap(registrar: FlutterPluginRegistrar, map: [String:Any?]?) -> WebMessageListener? {
guard let map = map else {
return nil
}
return WebMessageListener(
registrar: registrar,
id: map["id"] as! String,
jsObjectName: map["jsObjectName"] as! String,
allowedOriginRules: Set(map["allowedOriginRules"] as! [String])
@ -177,6 +180,7 @@ public class WebMessageListener : FlutterMethodCallDelegate {
channelDelegate?.dispose()
channelDelegate = nil
webView = nil
registrar = nil
}
deinit {

View File

@ -497,6 +497,10 @@ public class WebViewChannelDelegate : ChannelDelegate {
case .createWebMessageChannel:
if let webView = webView {
let _ = webView.createWebMessageChannel { (webMessageChannel) in
guard let webMessageChannel = webMessageChannel else {
result(nil)
return
}
result(webMessageChannel.toMap())
}
} else {
@ -532,9 +536,9 @@ public class WebViewChannelDelegate : ChannelDelegate {
}
break
case .addWebMessageListener:
if let webView = webView {
if let webView = webView, let registrar = webView.registrar {
let webMessageListenerMap = arguments!["webMessageListener"] as! [String: Any?]
let webMessageListener = WebMessageListener.fromMap(map: webMessageListenerMap)!
let webMessageListener = WebMessageListener.fromMap(registrar: registrar, map: webMessageListenerMap)!
do {
try webView.addWebMessageListener(webMessageListener: webMessageListener)
result(false)

View File

@ -10,13 +10,13 @@ import WebKit
public class InAppWebViewStatic: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_static"
static var registrar: FlutterPluginRegistrar?
static var webViewForUserAgent: WKWebView?
static var defaultUserAgent: String?
var plugin: SwiftFlutterPlugin?
var webViewForUserAgent: WKWebView?
var defaultUserAgent: String?
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: InAppWebViewStatic.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger()))
InAppWebViewStatic.registrar = registrar
init(plugin: SwiftFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: InAppWebViewStatic.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger()))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -24,7 +24,7 @@ public class InAppWebViewStatic: ChannelDelegate {
switch call.method {
case "getDefaultUserAgent":
InAppWebViewStatic.getDefaultUserAgent(completionHandler: { (value) in
getDefaultUserAgent(completionHandler: { (value) in
result(value)
})
break
@ -42,10 +42,10 @@ public class InAppWebViewStatic: ChannelDelegate {
}
}
static public func getDefaultUserAgent(completionHandler: @escaping (_ value: String?) -> Void) {
public func getDefaultUserAgent(completionHandler: @escaping (_ value: String?) -> Void) {
if defaultUserAgent == nil {
InAppWebViewStatic.webViewForUserAgent = WKWebView()
InAppWebViewStatic.webViewForUserAgent?.evaluateJavaScript("navigator.userAgent") { (value, error) in
webViewForUserAgent = WKWebView()
webViewForUserAgent?.evaluateJavaScript("navigator.userAgent") { (value, error) in
if error != nil {
print("Error occured to get userAgent")
@ -55,8 +55,8 @@ public class InAppWebViewStatic: ChannelDelegate {
}
if let unwrappedUserAgent = value as? String {
InAppWebViewStatic.defaultUserAgent = unwrappedUserAgent
completionHandler(defaultUserAgent)
self.defaultUserAgent = unwrappedUserAgent
completionHandler(self.defaultUserAgent)
} else {
print("Failed to get userAgent")
}
@ -69,9 +69,9 @@ public class InAppWebViewStatic: ChannelDelegate {
public override func dispose() {
super.dispose()
InAppWebViewStatic.registrar = nil
InAppWebViewStatic.webViewForUserAgent = nil
InAppWebViewStatic.defaultUserAgent = nil
plugin = nil
webViewForUserAgent = nil
defaultUserAgent = nil
}
deinit {

View File

@ -11,13 +11,12 @@ import WebKit
@available(iOS 11.0, *)
public class MyCookieManager: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_cookiemanager"
static var registrar: FlutterPluginRegistrar?
static var httpCookieStore: WKHTTPCookieStore?
var plugin: SwiftFlutterPlugin?
static var httpCookieStore = WKWebsiteDataStore.default().httpCookieStore
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: MyCookieManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger()))
MyCookieManager.registrar = registrar
MyCookieManager.httpCookieStore = WKWebsiteDataStore.default().httpCookieStore
init(plugin: SwiftFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: MyCookieManager.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger()))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -92,11 +91,6 @@ public class MyCookieManager: ChannelDelegate {
isHttpOnly: Bool?,
sameSite: String?,
result: @escaping FlutterResult) {
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
result(false)
return
}
var properties: [HTTPCookiePropertyKey: Any] = [:]
properties[.originURL] = url
properties[.name] = name
@ -139,7 +133,7 @@ public class MyCookieManager: ChannelDelegate {
let cookie = HTTPCookie(properties: properties)!
httpCookieStore.setCookie(cookie, completionHandler: {() in
MyCookieManager.httpCookieStore.setCookie(cookie, completionHandler: {() in
result(true)
})
}
@ -147,13 +141,8 @@ public class MyCookieManager: ChannelDelegate {
public static func getCookies(url: String, result: @escaping FlutterResult) {
var cookieList: [[String: Any?]] = []
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
result(cookieList)
return
}
if let urlHost = URL(string: url)?.host {
httpCookieStore.getAllCookies { (cookies) in
MyCookieManager.httpCookieStore.getAllCookies { (cookies) in
for cookie in cookies {
if urlHost.hasSuffix(cookie.domain) || ".\(urlHost)".hasSuffix(cookie.domain) {
var sameSite: String? = nil
@ -195,12 +184,7 @@ public class MyCookieManager: ChannelDelegate {
public static func getAllCookies(result: @escaping FlutterResult) {
var cookieList: [[String: Any?]] = []
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
result(cookieList)
return
}
httpCookieStore.getAllCookies { (cookies) in
MyCookieManager.httpCookieStore.getAllCookies { (cookies) in
for cookie in cookies {
var sameSite: String? = nil
if #available(iOS 13.0, *) {
@ -232,13 +216,8 @@ public class MyCookieManager: ChannelDelegate {
}
public static func deleteCookie(url: String, name: String, path: String, domain: String?, result: @escaping FlutterResult) {
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
result(false)
return
}
var domain = domain
httpCookieStore.getAllCookies { (cookies) in
MyCookieManager.httpCookieStore.getAllCookies { (cookies) in
for cookie in cookies {
var originURL = url
if cookie.properties![.originURL] is String {
@ -255,7 +234,7 @@ public class MyCookieManager: ChannelDelegate {
}
}
if let domain = domain, cookie.domain == domain, cookie.name == name, cookie.path == path {
httpCookieStore.delete(cookie, completionHandler: {
MyCookieManager.httpCookieStore.delete(cookie, completionHandler: {
result(true)
})
return
@ -266,13 +245,8 @@ public class MyCookieManager: ChannelDelegate {
}
public static func deleteCookies(url: String, path: String, domain: String?, result: @escaping FlutterResult) {
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
result(false)
return
}
var domain = domain
httpCookieStore.getAllCookies { (cookies) in
MyCookieManager.httpCookieStore.getAllCookies { (cookies) in
for cookie in cookies {
var originURL = url
if cookie.properties![.originURL] is String {
@ -289,7 +263,7 @@ public class MyCookieManager: ChannelDelegate {
}
}
if let domain = domain, cookie.domain == domain, cookie.path == path {
httpCookieStore.delete(cookie, completionHandler: nil)
MyCookieManager.httpCookieStore.delete(cookie, completionHandler: nil)
}
}
result(true)
@ -306,8 +280,7 @@ public class MyCookieManager: ChannelDelegate {
public override func dispose() {
super.dispose()
MyCookieManager.registrar = nil
MyCookieManager.httpCookieStore = nil
plugin = nil
}
deinit {

View File

@ -11,13 +11,12 @@ import WebKit
@available(iOS 9.0, *)
public class MyWebStorageManager: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_webstoragemanager"
static var registrar: FlutterPluginRegistrar?
static var websiteDataStore: WKWebsiteDataStore?
var plugin: SwiftFlutterPlugin?
static var websiteDataStore = WKWebsiteDataStore.default()
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: MyWebStorageManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger()))
MyWebStorageManager.registrar = registrar
MyWebStorageManager.websiteDataStore = WKWebsiteDataStore.default()
init(plugin: SwiftFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: MyWebStorageManager.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger()))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -45,13 +44,8 @@ public class MyWebStorageManager: ChannelDelegate {
public static func fetchDataRecords(dataTypes: Set<String>, result: @escaping FlutterResult) {
var recordList: [[String: Any?]] = []
guard let websiteDataStore = MyWebStorageManager.websiteDataStore else {
result(recordList)
return
}
websiteDataStore.fetchDataRecords(ofTypes: dataTypes) { (data) in
MyWebStorageManager.websiteDataStore.fetchDataRecords(ofTypes: dataTypes) { (data) in
for record in data {
recordList.append([
"displayName": record.displayName,
@ -66,13 +60,8 @@ public class MyWebStorageManager: ChannelDelegate {
public static func removeDataFor(dataTypes: Set<String>, recordList: [[String: Any?]], result: @escaping FlutterResult) {
var records: [WKWebsiteDataRecord] = []
guard let websiteDataStore = MyWebStorageManager.websiteDataStore else {
result(false)
return
}
websiteDataStore.fetchDataRecords(ofTypes: dataTypes) { (data) in
MyWebStorageManager.websiteDataStore.fetchDataRecords(ofTypes: dataTypes) { (data) in
for record in data {
for r in recordList {
let displayName = r["displayName"] as! String
@ -82,28 +71,22 @@ public class MyWebStorageManager: ChannelDelegate {
}
}
}
websiteDataStore.removeData(ofTypes: dataTypes, for: records) {
MyWebStorageManager.websiteDataStore.removeData(ofTypes: dataTypes, for: records) {
result(true)
}
}
}
public static func removeDataModifiedSince(dataTypes: Set<String>, timestamp: Int64, result: @escaping FlutterResult) {
guard let websiteDataStore = MyWebStorageManager.websiteDataStore else {
result(false)
return
}
let date = NSDate(timeIntervalSince1970: TimeInterval(timestamp))
websiteDataStore.removeData(ofTypes: dataTypes, modifiedSince: date as Date) {
MyWebStorageManager.websiteDataStore.removeData(ofTypes: dataTypes, modifiedSince: date as Date) {
result(true)
}
}
public override func dispose() {
super.dispose()
MyWebStorageManager.registrar = nil
MyWebStorageManager.websiteDataStore = nil
plugin = nil
}
deinit {

View File

@ -9,11 +9,11 @@ import Foundation
public class PlatformUtil: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_platformutil"
static var registrar: FlutterPluginRegistrar?
var plugin: SwiftFlutterPlugin?
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: PlatformUtil.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger()))
InAppWebViewStatic.registrar = registrar
init(plugin: SwiftFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: PlatformUtil.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger()))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -57,7 +57,7 @@ public class PlatformUtil: ChannelDelegate {
public override func dispose() {
super.dispose()
PlatformUtil.registrar = nil
plugin = nil
}
deinit {

View File

@ -18,6 +18,7 @@ public enum PrintJobState: Int {
public class PrintJobController : NSObject, Disposable, UIPrintInteractionControllerDelegate {
static let METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_printjobcontroller_"
var id: String
var registrar: FlutterPluginRegistrar?
var job: UIPrintInteractionController?
var settings: PrintJobSettings?
var printFormatter: UIPrintFormatter?
@ -26,8 +27,9 @@ public class PrintJobController : NSObject, Disposable, UIPrintInteractionContro
var state = PrintJobState.created
var creationTime = Int64(Date().timeIntervalSince1970 * 1000)
public init(id: String, job: UIPrintInteractionController? = nil, settings: PrintJobSettings? = nil) {
public init(registrar: FlutterPluginRegistrar, id: String, job: UIPrintInteractionController? = nil, settings: PrintJobSettings? = nil) {
self.id = id
self.registrar = registrar
super.init()
self.job = job
self.settings = settings
@ -35,7 +37,7 @@ public class PrintJobController : NSObject, Disposable, UIPrintInteractionContro
self.printPageRenderer = job?.printPageRenderer
self.job?.delegate = self
let channel = FlutterMethodChannel(name: PrintJobController.METHOD_CHANNEL_NAME_PREFIX + id,
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
binaryMessenger: registrar.messenger())
self.channelDelegate = PrintJobChannelDelegate(printJobController: self, channel: channel)
}
@ -92,5 +94,6 @@ public class PrintJobController : NSObject, Disposable, UIPrintInteractionContro
job?.dismiss(animated: false)
job = nil
PrintJobManager.jobs[id] = nil
registrar = nil
}
}

View File

@ -14,14 +14,14 @@ import SafariServices
public class ChromeSafariBrowserManager: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_chromesafaribrowser"
static var registrar: FlutterPluginRegistrar?
var plugin: SwiftFlutterPlugin?
static var browsers: [String: SafariViewController?] = [:]
@available(iOS 15.0, *)
static var prewarmingTokens: [String: SFSafariViewController.PrewarmingToken?] = [:]
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: ChromeSafariBrowserManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger()))
ChromeSafariBrowserManager.registrar = registrar
init(plugin: SwiftFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: ChromeSafariBrowserManager.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger()))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -89,7 +89,7 @@ public class ChromeSafariBrowserManager: ChannelDelegate {
public func open(id: String, url: String, settings: [String: Any?], menuItemList: [[String: Any]], result: @escaping FlutterResult) {
let absoluteUrl = URL(string: url)!.absoluteURL
if #available(iOS 9.0, *) {
if #available(iOS 9.0, *), let plugin = plugin {
if let flutterViewController = UIApplication.shared.delegate?.window.unsafelyUnwrapped?.rootViewController {
// flutterViewController could be casted to FlutterViewController if needed
@ -101,11 +101,11 @@ public class ChromeSafariBrowserManager: ChannelDelegate {
if #available(iOS 11.0, *) {
let config = SFSafariViewController.Configuration()
safari = SafariViewController(id: id, url: absoluteUrl, configuration: config,
safari = SafariViewController(plugin: plugin, id: id, url: absoluteUrl, configuration: config,
menuItemList: menuItemList, safariSettings: safariSettings)
} else {
// Fallback on earlier versions
safari = SafariViewController(id: id, url: absoluteUrl, entersReaderIfAvailable: safariSettings.entersReaderIfAvailable,
safari = SafariViewController(plugin: plugin, id: id, url: absoluteUrl, entersReaderIfAvailable: safariSettings.entersReaderIfAvailable,
menuItemList: menuItemList, safariSettings: safariSettings)
}
@ -125,7 +125,6 @@ public class ChromeSafariBrowserManager: ChannelDelegate {
public override func dispose() {
super.dispose()
ChromeSafariBrowserManager.registrar = nil
let browsers = ChromeSafariBrowserManager.browsers.values
browsers.forEach { (browser: SafariViewController?) in
browser?.close(result: nil)
@ -138,6 +137,7 @@ public class ChromeSafariBrowserManager: ChannelDelegate {
}
ChromeSafariBrowserManager.prewarmingTokens.removeAll()
}
plugin = nil
}
deinit {

View File

@ -14,28 +14,31 @@ public class SafariViewController: SFSafariViewController, SFSafariViewControlle
var channelDelegate: SafariViewControllerChannelDelegate?
var safariSettings: SafariBrowserSettings
var id: String
var plugin: SwiftFlutterPlugin?
var menuItemList: [[String: Any]] = []
@available(iOS 11.0, *)
public init(id: String, url: URL, configuration: SFSafariViewController.Configuration, menuItemList: [[String: Any]] = [], safariSettings: SafariBrowserSettings) {
public init(plugin: SwiftFlutterPlugin, id: String, url: URL, configuration: SFSafariViewController.Configuration, menuItemList: [[String: Any]] = [], safariSettings: SafariBrowserSettings) {
self.id = id
self.plugin = plugin
self.menuItemList = menuItemList
self.safariSettings = safariSettings
SafariViewController.prepareConfig(configuration: configuration, safariSettings: safariSettings)
super.init(url: url, configuration: configuration)
let channel = FlutterMethodChannel(name: SafariViewController.METHOD_CHANNEL_NAME_PREFIX + id,
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
binaryMessenger: plugin.registrar!.messenger())
self.channelDelegate = SafariViewControllerChannelDelegate(safariViewController: self, channel: channel)
self.delegate = self
}
public init(id: String, url: URL, entersReaderIfAvailable: Bool, menuItemList: [[String: Any]] = [], safariSettings: SafariBrowserSettings) {
public init(plugin: SwiftFlutterPlugin, id: String, url: URL, entersReaderIfAvailable: Bool, menuItemList: [[String: Any]] = [], safariSettings: SafariBrowserSettings) {
self.id = id
self.plugin = plugin
self.menuItemList = menuItemList
self.safariSettings = safariSettings
super.init(url: url, entersReaderIfAvailable: entersReaderIfAvailable)
let channel = FlutterMethodChannel(name: SafariViewController.METHOD_CHANNEL_NAME_PREFIX + id,
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
binaryMessenger: plugin.registrar!.messenger())
self.channelDelegate = SafariViewControllerChannelDelegate(safariViewController: self, channel: channel)
self.delegate = self
}
@ -123,6 +126,7 @@ public class SafariViewController: SFSafariViewController, SFSafariViewControlle
channelDelegate = nil
delegate = nil
ChromeSafariBrowserManager.browsers[id] = nil
plugin = nil
}
deinit {

View File

@ -24,7 +24,6 @@ import SafariServices
public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
static var instance: SwiftFlutterPlugin?
var registrar: FlutterPluginRegistrar?
var platformUtil: PlatformUtil?
var inAppWebViewStatic: InAppWebViewStatic?
@ -46,24 +45,24 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
self.registrar = registrar
registrar.register(FlutterWebViewFactory(registrar: registrar) as FlutterPlatformViewFactory, withId: FlutterWebViewFactory.VIEW_TYPE_ID)
platformUtil = PlatformUtil(registrar: registrar)
inAppBrowserManager = InAppBrowserManager(registrar: registrar)
headlessInAppWebViewManager = HeadlessInAppWebViewManager(registrar: registrar)
chromeSafariBrowserManager = ChromeSafariBrowserManager(registrar: registrar)
inAppWebViewStatic = InAppWebViewStatic(registrar: registrar)
credentialDatabase = CredentialDatabase(registrar: registrar)
platformUtil = PlatformUtil(plugin: self)
inAppBrowserManager = InAppBrowserManager(plugin: self)
headlessInAppWebViewManager = HeadlessInAppWebViewManager(plugin: self)
chromeSafariBrowserManager = ChromeSafariBrowserManager(plugin: self)
inAppWebViewStatic = InAppWebViewStatic(plugin: self)
credentialDatabase = CredentialDatabase(plugin: self)
if #available(iOS 11.0, *) {
myCookieManager = MyCookieManager(registrar: registrar)
myCookieManager = MyCookieManager(plugin: self)
}
if #available(iOS 9.0, *) {
myWebStorageManager = MyWebStorageManager(registrar: registrar)
myWebStorageManager = MyWebStorageManager(plugin: self)
}
webAuthenticationSessionManager = WebAuthenticationSessionManager(registrar: registrar)
webAuthenticationSessionManager = WebAuthenticationSessionManager(plugin: self)
printJobManager = PrintJobManager()
}
public static func register(with registrar: FlutterPluginRegistrar) {
SwiftFlutterPlugin.instance = SwiftFlutterPlugin(with: registrar)
let _ = SwiftFlutterPlugin(with: registrar)
}
public func detachFromEngine(for registrar: FlutterPluginRegistrar) {

View File

@ -11,16 +11,16 @@ import WebKit
var SharedLastTouchPointTimestamp: [InAppWebView: Int64] = [:]
public class Util {
public static func getUrlAsset(assetFilePath: String) throws -> URL {
let key = SwiftFlutterPlugin.instance?.registrar?.lookupKey(forAsset: assetFilePath)
public static func getUrlAsset(registrar: FlutterPluginRegistrar, assetFilePath: String) throws -> URL {
let key = registrar.lookupKey(forAsset: assetFilePath)
guard let assetURL = Bundle.main.url(forResource: key, withExtension: nil) else {
throw NSError(domain: assetFilePath + " asset file cannot be found!", code: 0)
}
return assetURL
}
public static func getAbsPathAsset(assetFilePath: String) throws -> String {
let key = SwiftFlutterPlugin.instance?.registrar?.lookupKey(forAsset: assetFilePath)
public static func getAbsPathAsset(registrar: FlutterPluginRegistrar, assetFilePath: String) throws -> String {
let key = registrar.lookupKey(forAsset: assetFilePath)
guard let assetAbsPath = Bundle.main.path(forResource: key, ofType: nil) else {
throw NSError(domain: assetFilePath + " asset file cannot be found!", code: 0)
}

View File

@ -12,6 +12,7 @@ import SafariServices
public class WebAuthenticationSession : NSObject, ASWebAuthenticationPresentationContextProviding, Disposable {
static let METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_webauthenticationsession_"
var id: String
var plugin: SwiftFlutterPlugin?
var url: URL
var callbackURLScheme: String?
var settings: WebAuthenticationSessionSettings
@ -19,8 +20,9 @@ public class WebAuthenticationSession : NSObject, ASWebAuthenticationPresentatio
var channelDelegate: WebAuthenticationSessionChannelDelegate?
private var _canStart = true
public init(id: String, url: URL, callbackURLScheme: String?, settings: WebAuthenticationSessionSettings) {
public init(plugin: SwiftFlutterPlugin, id: String, url: URL, callbackURLScheme: String?, settings: WebAuthenticationSessionSettings) {
self.id = id
self.plugin = plugin
self.url = url
self.settings = settings
super.init()
@ -35,7 +37,7 @@ public class WebAuthenticationSession : NSObject, ASWebAuthenticationPresentatio
self.session = SFAuthenticationSession(url: self.url, callbackURLScheme: self.callbackURLScheme, completionHandler: self.completionHandler)
}
let channel = FlutterMethodChannel(name: WebAuthenticationSession.METHOD_CHANNEL_NAME_PREFIX + id,
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
binaryMessenger: plugin.registrar!.messenger())
self.channelDelegate = WebAuthenticationSessionChannelDelegate(webAuthenticationSession: self, channel: channel)
}
@ -97,6 +99,7 @@ public class WebAuthenticationSession : NSObject, ASWebAuthenticationPresentatio
channelDelegate = nil
session = nil
WebAuthenticationSessionManager.sessions[id] = nil
plugin = nil
}
deinit {

View File

@ -14,12 +14,12 @@ import SafariServices
public class WebAuthenticationSessionManager: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_webauthenticationsession"
static var registrar: FlutterPluginRegistrar?
var plugin: SwiftFlutterPlugin?
static var sessions: [String: WebAuthenticationSession?] = [:]
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: WebAuthenticationSessionManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger()))
WebAuthenticationSessionManager.registrar = registrar
init(plugin: SwiftFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: WebAuthenticationSessionManager.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger()))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -47,11 +47,11 @@ public class WebAuthenticationSessionManager: ChannelDelegate {
}
public func create(id: String, url: String, callbackURLScheme: String?, settings: [String: Any?], result: @escaping FlutterResult) {
if #available(iOS 11.0, *) {
if #available(iOS 11.0, *), let plugin = plugin {
let sessionUrl = URL(string: url) ?? URL(string: "about:blank")!
let initialSettings = WebAuthenticationSessionSettings()
let _ = initialSettings.parse(settings: settings)
let session = WebAuthenticationSession(id: id, url: sessionUrl, callbackURLScheme: callbackURLScheme, settings: initialSettings)
let session = WebAuthenticationSession(plugin: plugin, id: id, url: sessionUrl, callbackURLScheme: callbackURLScheme, settings: initialSettings)
session.prepare()
WebAuthenticationSessionManager.sessions[id] = session
result(true)
@ -63,13 +63,13 @@ public class WebAuthenticationSessionManager: ChannelDelegate {
public override func dispose() {
super.dispose()
WebAuthenticationSessionManager.registrar = nil
let sessions = WebAuthenticationSessionManager.sessions.values
sessions.forEach { (session: WebAuthenticationSession?) in
session?.cancel()
session?.dispose()
}
WebAuthenticationSessionManager.sessions.removeAll()
plugin = nil
}
deinit {

View File

@ -10,13 +10,12 @@ import FlutterMacOS
public class CredentialDatabase: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_credential_database"
static var registrar: FlutterPluginRegistrar?
static var credentialStore: URLCredentialStorage?
var plugin: InAppWebViewFlutterPlugin?
static var credentialStore = URLCredentialStorage.shared
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: CredentialDatabase.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger))
CredentialDatabase.registrar = registrar
CredentialDatabase.credentialStore = URLCredentialStorage.shared
init(plugin: InAppWebViewFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: CredentialDatabase.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -24,11 +23,8 @@ public class CredentialDatabase: ChannelDelegate {
switch call.method {
case "getAllAuthCredentials":
var allCredentials: [[String: Any?]] = []
guard let credentialStore = CredentialDatabase.credentialStore else {
result(allCredentials)
return
}
for (protectionSpace, credentials) in credentialStore.allCredentials {
for (protectionSpace, credentials) in CredentialDatabase.credentialStore.allCredentials {
var crendentials: [[String: Any?]] = []
for c in credentials {
let credential: [String: Any?] = c.value.toMap()
@ -46,11 +42,7 @@ public class CredentialDatabase: ChannelDelegate {
break
case "getHttpAuthCredentials":
var crendentials: [[String: Any?]] = []
guard let credentialStore = CredentialDatabase.credentialStore else {
result(crendentials)
return
}
let host = arguments!["host"] as! String
let urlProtocol = arguments!["protocol"] as? String
let urlPort = arguments!["port"] as? Int ?? 0
@ -59,7 +51,7 @@ public class CredentialDatabase: ChannelDelegate {
realm = nil
}
for (protectionSpace, credentials) in credentialStore.allCredentials {
for (protectionSpace, credentials) in CredentialDatabase.credentialStore.allCredentials {
if protectionSpace.host == host && protectionSpace.realm == realm &&
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
for c in credentials {
@ -71,11 +63,6 @@ public class CredentialDatabase: ChannelDelegate {
result(crendentials)
break
case "setHttpAuthCredential":
guard let credentialStore = CredentialDatabase.credentialStore else {
result(false)
return
}
let host = arguments!["host"] as! String
let urlProtocol = arguments!["protocol"] as? String
let urlPort = arguments!["port"] as? Int ?? 0
@ -86,17 +73,12 @@ public class CredentialDatabase: ChannelDelegate {
let username = arguments!["username"] as! String
let password = arguments!["password"] as! String
let credential = URLCredential(user: username, password: password, persistence: .permanent)
credentialStore.set(credential,
CredentialDatabase.credentialStore.set(credential,
for: URLProtectionSpace(host: host, port: urlPort, protocol: urlProtocol,
realm: realm, authenticationMethod: NSURLAuthenticationMethodHTTPBasic))
result(true)
break
case "removeHttpAuthCredential":
guard let credentialStore = CredentialDatabase.credentialStore else {
result(false)
return
}
let host = arguments!["host"] as! String
let urlProtocol = arguments!["protocol"] as? String
let urlPort = arguments!["port"] as? Int ?? 0
@ -110,7 +92,7 @@ public class CredentialDatabase: ChannelDelegate {
var credential: URLCredential? = nil;
var protectionSpaceCredential: URLProtectionSpace? = nil
for (protectionSpace, credentials) in credentialStore.allCredentials {
for (protectionSpace, credentials) in CredentialDatabase.credentialStore.allCredentials {
if protectionSpace.host == host && protectionSpace.realm == realm &&
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
for c in credentials {
@ -127,17 +109,12 @@ public class CredentialDatabase: ChannelDelegate {
}
if let c = credential, let protectionSpace = protectionSpaceCredential {
credentialStore.remove(c, for: protectionSpace)
CredentialDatabase.credentialStore.remove(c, for: protectionSpace)
}
result(true)
break
case "removeHttpAuthCredentials":
guard let credentialStore = CredentialDatabase.credentialStore else {
result(false)
return
}
let host = arguments!["host"] as! String
let urlProtocol = arguments!["protocol"] as? String
let urlPort = arguments!["port"] as? Int ?? 0
@ -149,7 +126,7 @@ public class CredentialDatabase: ChannelDelegate {
var credentialsToRemove: [URLCredential] = [];
var protectionSpaceCredential: URLProtectionSpace? = nil
for (protectionSpace, credentials) in credentialStore.allCredentials {
for (protectionSpace, credentials) in CredentialDatabase.credentialStore.allCredentials {
if protectionSpace.host == host && protectionSpace.realm == realm &&
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
protectionSpaceCredential = protectionSpace
@ -164,21 +141,16 @@ public class CredentialDatabase: ChannelDelegate {
if let protectionSpace = protectionSpaceCredential {
for credential in credentialsToRemove {
credentialStore.remove(credential, for: protectionSpace)
CredentialDatabase.credentialStore.remove(credential, for: protectionSpace)
}
}
result(true)
break
case "clearAllAuthCredentials":
guard let credentialStore = CredentialDatabase.credentialStore else {
result(false)
return
}
for (protectionSpace, credentials) in credentialStore.allCredentials {
for (protectionSpace, credentials) in CredentialDatabase.credentialStore.allCredentials {
for credential in credentials {
credentialStore.remove(credential.value, for: protectionSpace)
CredentialDatabase.credentialStore.remove(credential.value, for: protectionSpace)
}
}
result(true)
@ -191,8 +163,7 @@ public class CredentialDatabase: ChannelDelegate {
public override func dispose() {
super.dispose()
CredentialDatabase.registrar = nil
CredentialDatabase.credentialStore = nil
plugin = nil
}
deinit {

View File

@ -13,12 +13,14 @@ public class HeadlessInAppWebView : Disposable {
var id: String
var channelDelegate: HeadlessWebViewChannelDelegate?
var flutterWebView: FlutterWebViewController?
var plugin: InAppWebViewFlutterPlugin?
public init(id: String, flutterWebView: FlutterWebViewController) {
public init(plugin: InAppWebViewFlutterPlugin, id: String, flutterWebView: FlutterWebViewController) {
self.id = id
self.flutterWebView = flutterWebView
self.plugin = plugin
let channel = FlutterMethodChannel(name: HeadlessInAppWebView.METHOD_CHANNEL_NAME_PREFIX + id,
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger)
binaryMessenger: plugin.registrar!.messenger)
self.channelDelegate = HeadlessWebViewChannelDelegate(headlessWebView: self, channel: channel)
}
@ -84,6 +86,7 @@ public class HeadlessInAppWebView : Disposable {
view.superview?.removeFromSuperview()
}
flutterWebView = nil
plugin = nil
}
deinit {

View File

@ -15,12 +15,12 @@ import AVFoundation
public class HeadlessInAppWebViewManager: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_headless_inappwebview"
static var registrar: FlutterPluginRegistrar?
var plugin: InAppWebViewFlutterPlugin?
static var webViews: [String: HeadlessInAppWebView?] = [:]
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: HeadlessInAppWebViewManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger))
HeadlessInAppWebViewManager.registrar = registrar
init(plugin: InAppWebViewFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: HeadlessInAppWebViewManager.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -30,7 +30,7 @@ public class HeadlessInAppWebViewManager: ChannelDelegate {
switch call.method {
case "run":
let params = arguments!["params"] as! [String: Any?]
HeadlessInAppWebViewManager.run(id: id, params: params)
run(id: id, params: params)
result(true)
break
default:
@ -39,12 +39,15 @@ public class HeadlessInAppWebViewManager: ChannelDelegate {
}
}
public static func run(id: String, params: [String: Any?]) {
let flutterWebView = FlutterWebViewController(registrar: HeadlessInAppWebViewManager.registrar!,
public func run(id: String, params: [String: Any?]) {
guard let plugin = plugin, let registrar = plugin.registrar else {
return
}
let flutterWebView = FlutterWebViewController(registrar: registrar,
withFrame: CGRect.zero,
viewIdentifier: id,
params: params as NSDictionary)
let headlessInAppWebView = HeadlessInAppWebView(id: id, flutterWebView: flutterWebView)
let headlessInAppWebView = HeadlessInAppWebView(plugin: plugin, id: id, flutterWebView: flutterWebView)
HeadlessInAppWebViewManager.webViews[id] = headlessInAppWebView
headlessInAppWebView.prepare(params: params as NSDictionary)
@ -54,12 +57,12 @@ public class HeadlessInAppWebViewManager: ChannelDelegate {
public override func dispose() {
super.dispose()
HeadlessInAppWebViewManager.registrar = nil
let headlessWebViews = HeadlessInAppWebViewManager.webViews.values
headlessWebViews.forEach { (headlessWebView: HeadlessInAppWebView?) in
headlessWebView?.dispose()
}
HeadlessInAppWebViewManager.webViews.removeAll()
plugin = nil
}
deinit {

View File

@ -16,11 +16,11 @@ public class InAppBrowserManager: ChannelDelegate {
static let WEBVIEW_STORYBOARD = "WebView"
static let WEBVIEW_STORYBOARD_CONTROLLER_ID = "viewController"
static let NAV_STORYBOARD_CONTROLLER_ID = "navController"
static var registrar: FlutterPluginRegistrar?
var plugin: InAppWebViewFlutterPlugin?
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: InAppBrowserManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger))
InAppBrowserManager.registrar = registrar
init(plugin: InAppWebViewFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: InAppBrowserManager.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -60,6 +60,7 @@ public class InAppBrowserManager: ChannelDelegate {
let _ = webViewSettings.parse(settings: settings)
let webViewController = InAppBrowserWebViewController()
webViewController.plugin = plugin
webViewController.browserSettings = browserSettings
webViewController.webViewSettings = webViewSettings
@ -103,7 +104,7 @@ public class InAppBrowserManager: ChannelDelegate {
public override func dispose() {
super.dispose()
InAppBrowserManager.registrar = nil
plugin = nil
}
deinit {

View File

@ -17,6 +17,7 @@ public class InAppBrowserWebViewController: NSViewController, InAppBrowserDelega
var window: InAppBrowserWindow?
var id: String = ""
var plugin: InAppWebViewFlutterPlugin?
var windowId: Int64?
var webView: InAppWebView?
var channelDelegate: InAppBrowserChannelDelegate?
@ -32,7 +33,11 @@ public class InAppBrowserWebViewController: NSViewController, InAppBrowserDelega
var isHidden = false
public override func loadView() {
let channel = FlutterMethodChannel(name: InAppBrowserWebViewController.METHOD_CHANNEL_NAME_PREFIX + id, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger)
guard let registrar = plugin?.registrar else {
return
}
let channel = FlutterMethodChannel(name: InAppBrowserWebViewController.METHOD_CHANNEL_NAME_PREFIX + id, binaryMessenger: registrar.messenger)
channelDelegate = InAppBrowserChannelDelegate(channel: channel)
var userScripts: [UserScript] = []
@ -61,7 +66,7 @@ public class InAppBrowserWebViewController: NSViewController, InAppBrowserDelega
webView.channelDelegate = WebViewChannelDelegate(webView: webView, channel: channel)
let findInteractionController = FindInteractionController(
registrar: SwiftFlutterPlugin.instance!.registrar!,
registrar: registrar,
id: id, webView: webView, settings: nil)
webView.findInteractionController = findInteractionController
findInteractionController.prepare()
@ -304,6 +309,7 @@ public class InAppBrowserWebViewController: NSViewController, InAppBrowserDelega
webView?.dispose()
webView = nil
window = nil
plugin = nil
}
deinit {

View File

@ -220,19 +220,18 @@ public class InAppBrowserWindow : NSWindow, NSWindowDelegate, NSToolbarDelegate,
public func hide() {
orderOut(self)
}
public func show() {
let mainWindow = parent ?? NSApplication.shared.mainWindow
if #available(macOS 10.12, *),
!(NSApplication.shared.mainWindow?.tabbedWindows?.contains(self) ?? false),
!(mainWindow?.tabbedWindows?.contains(self) ?? false),
browserSettings?.windowType == .tabbed {
NSApplication.shared.mainWindow?.addTabbedWindow(self, ordered: .above)
} else if !(NSApplication.shared.mainWindow?.childWindows?.contains(self) ?? false) {
NSApplication.shared.mainWindow?.addChildWindow(self, ordered: .above)
} else {
orderFront(self)
mainWindow?.addTabbedWindow(self, ordered: .above)
} else if !(mainWindow?.childWindows?.contains(self) ?? false) {
mainWindow?.addChildWindow(self, ordered: .above)
}
makeKeyAndOrderFront(self)
NSApplication.shared.activate(ignoringOtherApps: true)
}
@ -261,6 +260,19 @@ public class InAppBrowserWindow : NSWindow, NSWindowDelegate, NSToolbarDelegate,
backgroundColor = nil
}
}
if #available(macOS 11.0, *), newSettingsMap["windowTitlebarSeparatorStyle"] != nil,
browserSettings?.windowTitlebarSeparatorStyle != newSettings.windowTitlebarSeparatorStyle {
titlebarSeparatorStyle = newSettings.windowTitlebarSeparatorStyle!
}
if newSettingsMap["windowAlphaValue"] != nil, browserSettings?.windowAlphaValue != newSettings.windowAlphaValue {
alphaValue = newSettings.windowAlphaValue
}
if newSettingsMap["windowStyleMask"] != nil, browserSettings?.windowStyleMask != newSettings.windowStyleMask {
styleMask = newSettings.windowStyleMask!
}
if newSettingsMap["windowFrame"] != nil, browserSettings?.windowFrame != newSettings.windowFrame {
setFrame(newSettings.windowFrame!, display: true)
}
browserSettings = newSettings
}

View File

@ -52,7 +52,7 @@ public class FlutterWebViewController: NSObject, /*FlutterPlatformView,*/ Dispos
}
let findInteractionController = FindInteractionController(
registrar: SwiftFlutterPlugin.instance!.registrar!,
registrar: registrar,
id: viewId, webView: webView!, settings: nil)
webView!.findInteractionController = findInteractionController
findInteractionController.prepare()

View File

@ -16,6 +16,7 @@ public class InAppWebView: WKWebView, WKUIDelegate,
static var METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_"
var id: Any? // viewId
var registrar: FlutterPluginRegistrar?
var windowId: Int64?
var windowCreated = false
var inAppBrowserDelegate: InAppBrowserDelegate?
@ -53,6 +54,7 @@ public class InAppWebView: WKWebView, WKUIDelegate,
userScripts: [UserScript] = []) {
super.init(frame: frame, configuration: configuration)
self.id = id
self.registrar = registrar
if let id = id, let registrar = registrar {
let channel = FlutterMethodChannel(name: InAppWebView.METHOD_CHANNEL_NAME_PREFIX + String(describing: id),
binaryMessenger: registrar.messenger)
@ -1367,8 +1369,8 @@ public class InAppWebView: WKWebView, WKUIDelegate,
completionHandler(.useCredential, credential)
break
case 2:
if InAppWebView.credentialsProposed.count == 0, let credentialStore = CredentialDatabase.credentialStore {
for (protectionSpace, credentials) in credentialStore.allCredentials {
if InAppWebView.credentialsProposed.count == 0 {
for (protectionSpace, credentials) in CredentialDatabase.credentialStore.allCredentials {
if protectionSpace.host == host && protectionSpace.realm == realm &&
protectionSpace.protocol == prot && protectionSpace.port == port {
for credential in credentials {
@ -2356,8 +2358,8 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
}
}
if let id = printJobId {
let printJob = PrintJobController(id: id, job: printOperation, settings: settings)
if let id = printJobId, let registrar = registrar {
let printJob = PrintJobController(registrar: registrar, id: id, job: printOperation, settings: settings)
PrintJobManager.jobs[id] = printJob
printJob.present(parentWindow: window, completionHandler: completionHandler)
} else if let window = window {
@ -2455,9 +2457,13 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
}
}
public func createWebMessageChannel(completionHandler: ((WebMessageChannel) -> Void)? = nil) -> WebMessageChannel {
public func createWebMessageChannel(completionHandler: ((WebMessageChannel?) -> Void)? = nil) -> WebMessageChannel? {
guard let registrar = registrar else {
completionHandler?(nil)
return nil
}
let id = NSUUID().uuidString
let webMessageChannel = WebMessageChannel(id: id)
let webMessageChannel = WebMessageChannel(registrar: registrar, id: id)
webMessageChannel.initJsInstance(webView: self, completionHandler: completionHandler)
webMessageChannels[id] = webMessageChannel
@ -2576,6 +2582,7 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
isPausedTimersCompletionHandler = nil
callAsyncJavaScriptBelowIOS14Results.removeAll()
super.removeFromSuperview()
registrar = nil
}
deinit {

View File

@ -14,12 +14,14 @@ public class WebMessageChannel : FlutterMethodCallDelegate {
var channelDelegate: WebMessageChannelChannelDelegate?
weak var webView: InAppWebView?
var ports: [WebMessagePort] = []
var registrar: FlutterPluginRegistrar?
public init(id: String) {
public init(registrar: FlutterPluginRegistrar, id: String) {
self.id = id
self.registrar = registrar
super.init()
let channel = FlutterMethodChannel(name: WebMessageChannel.METHOD_CHANNEL_NAME_PREFIX + id,
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger)
binaryMessenger: registrar.messenger)
self.channelDelegate = WebMessageChannelChannelDelegate(webMessageChannel: self, channel: channel)
self.ports = [
WebMessagePort(name: "port1", webMessageChannel: self),
@ -27,7 +29,7 @@ public class WebMessageChannel : FlutterMethodCallDelegate {
]
}
public func initJsInstance(webView: InAppWebView, completionHandler: ((WebMessageChannel) -> Void)? = nil) {
public func initJsInstance(webView: InAppWebView, completionHandler: ((WebMessageChannel?) -> Void)? = nil) {
self.webView = webView
if let webView = self.webView {
webView.evaluateJavascript(source: """
@ -38,7 +40,7 @@ public class WebMessageChannel : FlutterMethodCallDelegate {
completionHandler?(self)
}
} else {
completionHandler?(self)
completionHandler?(nil)
}
}
@ -66,6 +68,7 @@ public class WebMessageChannel : FlutterMethodCallDelegate {
})();
""")
webView = nil
registrar = nil
}
deinit {

View File

@ -16,14 +16,16 @@ public class WebMessageListener : FlutterMethodCallDelegate {
var allowedOriginRules: Set<String>
var channelDelegate: WebMessageListenerChannelDelegate?
weak var webView: InAppWebView?
var registrar: FlutterPluginRegistrar?
public init(id: String, jsObjectName: String, allowedOriginRules: Set<String>) {
public init(registrar: FlutterPluginRegistrar, id: String, jsObjectName: String, allowedOriginRules: Set<String>) {
self.id = id
self.registrar = registrar
self.jsObjectName = jsObjectName
self.allowedOriginRules = allowedOriginRules
super.init()
let channel = FlutterMethodChannel(name: WebMessageListener.METHOD_CHANNEL_NAME_PREFIX + self.id + "_" + self.jsObjectName,
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger)
binaryMessenger: registrar.messenger)
self.channelDelegate = WebMessageListenerChannelDelegate(webMessageListener: self, channel: channel)
}
@ -115,11 +117,12 @@ public class WebMessageListener : FlutterMethodCallDelegate {
}
}
public static func fromMap(map: [String:Any?]?) -> WebMessageListener? {
public static func fromMap(registrar: FlutterPluginRegistrar, map: [String:Any?]?) -> WebMessageListener? {
guard let map = map else {
return nil
}
return WebMessageListener(
registrar: registrar,
id: map["id"] as! String,
jsObjectName: map["jsObjectName"] as! String,
allowedOriginRules: Set(map["allowedOriginRules"] as! [String])
@ -178,6 +181,7 @@ public class WebMessageListener : FlutterMethodCallDelegate {
channelDelegate?.dispose()
channelDelegate = nil
webView = nil
registrar = nil
}
deinit {

View File

@ -468,6 +468,10 @@ public class WebViewChannelDelegate : ChannelDelegate {
case .createWebMessageChannel:
if let webView = webView {
let _ = webView.createWebMessageChannel { (webMessageChannel) in
guard let webMessageChannel = webMessageChannel else {
result(nil)
return
}
result(webMessageChannel.toMap())
}
} else {
@ -503,9 +507,9 @@ public class WebViewChannelDelegate : ChannelDelegate {
}
break
case .addWebMessageListener:
if let webView = webView {
if let webView = webView, let registrar = webView.registrar {
let webMessageListenerMap = arguments!["webMessageListener"] as! [String: Any?]
let webMessageListener = WebMessageListener.fromMap(map: webMessageListenerMap)!
let webMessageListener = WebMessageListener.fromMap(registrar: registrar, map: webMessageListenerMap)!
do {
try webView.addWebMessageListener(webMessageListener: webMessageListener)
result(false)

View File

@ -1,8 +1,86 @@
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
import Cocoa
import FlutterMacOS
import AppKit
import WebKit
import Foundation
import AVFoundation
import SafariServices
public class InAppWebViewFlutterPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
SwiftFlutterPlugin.register(with: registrar)
}
var registrar: FlutterPluginRegistrar?
var platformUtil: PlatformUtil?
var inAppWebViewStatic: InAppWebViewStatic?
var myCookieManager: Any?
var myWebStorageManager: MyWebStorageManager?
var credentialDatabase: CredentialDatabase?
var inAppBrowserManager: InAppBrowserManager?
var headlessInAppWebViewManager: HeadlessInAppWebViewManager?
var webAuthenticationSessionManager: WebAuthenticationSessionManager?
// var printJobManager: PrintJobManager?
var webViewControllers: [String: InAppBrowserWebViewController?] = [:]
var safariViewControllers: [String: Any?] = [:]
public init(with registrar: FlutterPluginRegistrar) {
super.init()
self.registrar = registrar
registrar.register(FlutterWebViewFactory(registrar: registrar) as FlutterPlatformViewFactory, withId: FlutterWebViewFactory.VIEW_TYPE_ID)
platformUtil = PlatformUtil(plugin: self)
inAppBrowserManager = InAppBrowserManager(plugin: self)
headlessInAppWebViewManager = HeadlessInAppWebViewManager(plugin: self)
inAppWebViewStatic = InAppWebViewStatic(plugin: self)
credentialDatabase = CredentialDatabase(plugin: self)
if #available(macOS 10.13, *) {
myCookieManager = MyCookieManager(plugin: self)
}
myWebStorageManager = MyWebStorageManager(plugin: self)
webAuthenticationSessionManager = WebAuthenticationSessionManager(plugin: self)
// printJobManager = PrintJobManager()
}
public static func register(with registrar: FlutterPluginRegistrar) {
let _ = InAppWebViewFlutterPlugin(with: registrar)
}
public func detachFromEngine(for registrar: FlutterPluginRegistrar) {
platformUtil?.dispose()
platformUtil = nil
inAppBrowserManager?.dispose()
inAppBrowserManager = nil
headlessInAppWebViewManager?.dispose()
headlessInAppWebViewManager = nil
inAppWebViewStatic?.dispose()
inAppWebViewStatic = nil
credentialDatabase?.dispose()
credentialDatabase = nil
if #available(macOS 10.13, *) {
(myCookieManager as! MyCookieManager?)?.dispose()
myCookieManager = nil
}
myWebStorageManager?.dispose()
myWebStorageManager = nil
webAuthenticationSessionManager?.dispose()
webAuthenticationSessionManager = nil
// printJobManager?.dispose()
// printJobManager = nil
}
}

View File

@ -11,13 +11,13 @@ import FlutterMacOS
public class InAppWebViewStatic: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_static"
static var registrar: FlutterPluginRegistrar?
static var webViewForUserAgent: WKWebView?
static var defaultUserAgent: String?
var plugin: InAppWebViewFlutterPlugin?
var webViewForUserAgent: WKWebView?
var defaultUserAgent: String?
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: InAppWebViewStatic.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger))
InAppWebViewStatic.registrar = registrar
init(plugin: InAppWebViewFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: InAppWebViewStatic.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -25,7 +25,7 @@ public class InAppWebViewStatic: ChannelDelegate {
switch call.method {
case "getDefaultUserAgent":
InAppWebViewStatic.getDefaultUserAgent(completionHandler: { (value) in
getDefaultUserAgent(completionHandler: { (value) in
result(value)
})
break
@ -43,10 +43,10 @@ public class InAppWebViewStatic: ChannelDelegate {
}
}
static public func getDefaultUserAgent(completionHandler: @escaping (_ value: String?) -> Void) {
public func getDefaultUserAgent(completionHandler: @escaping (_ value: String?) -> Void) {
if defaultUserAgent == nil {
InAppWebViewStatic.webViewForUserAgent = WKWebView()
InAppWebViewStatic.webViewForUserAgent?.evaluateJavaScript("navigator.userAgent") { (value, error) in
webViewForUserAgent = WKWebView()
webViewForUserAgent?.evaluateJavaScript("navigator.userAgent") { (value, error) in
if error != nil {
print("Error occured to get userAgent")
@ -56,8 +56,8 @@ public class InAppWebViewStatic: ChannelDelegate {
}
if let unwrappedUserAgent = value as? String {
InAppWebViewStatic.defaultUserAgent = unwrappedUserAgent
completionHandler(defaultUserAgent)
self.defaultUserAgent = unwrappedUserAgent
completionHandler(self.defaultUserAgent)
} else {
print("Failed to get userAgent")
}
@ -70,9 +70,9 @@ public class InAppWebViewStatic: ChannelDelegate {
public override func dispose() {
super.dispose()
InAppWebViewStatic.registrar = nil
InAppWebViewStatic.webViewForUserAgent = nil
InAppWebViewStatic.defaultUserAgent = nil
plugin = nil
webViewForUserAgent = nil
defaultUserAgent = nil
}
deinit {

View File

@ -12,13 +12,12 @@ import FlutterMacOS
@available(macOS 10.13, *)
public class MyCookieManager: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_cookiemanager"
static var registrar: FlutterPluginRegistrar?
static var httpCookieStore: WKHTTPCookieStore?
var plugin: InAppWebViewFlutterPlugin?
static var httpCookieStore = WKWebsiteDataStore.default().httpCookieStore
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: MyCookieManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger))
MyCookieManager.registrar = registrar
MyCookieManager.httpCookieStore = WKWebsiteDataStore.default().httpCookieStore
init(plugin: InAppWebViewFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: MyCookieManager.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -93,11 +92,6 @@ public class MyCookieManager: ChannelDelegate {
isHttpOnly: Bool?,
sameSite: String?,
result: @escaping FlutterResult) {
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
result(false)
return
}
var properties: [HTTPCookiePropertyKey: Any] = [:]
properties[.originURL] = url
properties[.name] = name
@ -140,7 +134,7 @@ public class MyCookieManager: ChannelDelegate {
let cookie = HTTPCookie(properties: properties)!
httpCookieStore.setCookie(cookie, completionHandler: {() in
MyCookieManager.httpCookieStore.setCookie(cookie, completionHandler: {() in
result(true)
})
}
@ -148,13 +142,8 @@ public class MyCookieManager: ChannelDelegate {
public static func getCookies(url: String, result: @escaping FlutterResult) {
var cookieList: [[String: Any?]] = []
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
result(cookieList)
return
}
if let urlHost = URL(string: url)?.host {
httpCookieStore.getAllCookies { (cookies) in
MyCookieManager.httpCookieStore.getAllCookies { (cookies) in
for cookie in cookies {
if urlHost.hasSuffix(cookie.domain) || ".\(urlHost)".hasSuffix(cookie.domain) {
var sameSite: String? = nil
@ -196,12 +185,7 @@ public class MyCookieManager: ChannelDelegate {
public static func getAllCookies(result: @escaping FlutterResult) {
var cookieList: [[String: Any?]] = []
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
result(cookieList)
return
}
httpCookieStore.getAllCookies { (cookies) in
MyCookieManager.httpCookieStore.getAllCookies { (cookies) in
for cookie in cookies {
var sameSite: String? = nil
if #available(macOS 10.15, *) {
@ -233,13 +217,8 @@ public class MyCookieManager: ChannelDelegate {
}
public static func deleteCookie(url: String, name: String, path: String, domain: String?, result: @escaping FlutterResult) {
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
result(false)
return
}
var domain = domain
httpCookieStore.getAllCookies { (cookies) in
MyCookieManager.httpCookieStore.getAllCookies { (cookies) in
for cookie in cookies {
var originURL = url
if cookie.properties![.originURL] is String {
@ -252,7 +231,7 @@ public class MyCookieManager: ChannelDelegate {
domain = domainUrl.host
}
if let domain = domain, cookie.domain == domain, cookie.name == name, cookie.path == path {
httpCookieStore.delete(cookie, completionHandler: {
MyCookieManager.httpCookieStore.delete(cookie, completionHandler: {
result(true)
})
return
@ -263,13 +242,8 @@ public class MyCookieManager: ChannelDelegate {
}
public static func deleteCookies(url: String, path: String, domain: String?, result: @escaping FlutterResult) {
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
result(false)
return
}
var domain = domain
httpCookieStore.getAllCookies { (cookies) in
MyCookieManager.httpCookieStore.getAllCookies { (cookies) in
for cookie in cookies {
var originURL = url
if cookie.properties![.originURL] is String {
@ -282,7 +256,7 @@ public class MyCookieManager: ChannelDelegate {
domain = domainUrl.host
}
if let domain = domain, cookie.domain == domain, cookie.path == path {
httpCookieStore.delete(cookie, completionHandler: nil)
MyCookieManager.httpCookieStore.delete(cookie, completionHandler: nil)
}
}
result(true)
@ -299,8 +273,7 @@ public class MyCookieManager: ChannelDelegate {
public override func dispose() {
super.dispose()
MyCookieManager.registrar = nil
MyCookieManager.httpCookieStore = nil
plugin = nil
}
deinit {

View File

@ -11,13 +11,12 @@ import FlutterMacOS
public class MyWebStorageManager: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_webstoragemanager"
static var registrar: FlutterPluginRegistrar?
static var websiteDataStore: WKWebsiteDataStore?
var plugin: InAppWebViewFlutterPlugin?
static var websiteDataStore = WKWebsiteDataStore.default()
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: MyWebStorageManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger))
MyWebStorageManager.registrar = registrar
MyWebStorageManager.websiteDataStore = WKWebsiteDataStore.default()
init(plugin: InAppWebViewFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: MyWebStorageManager.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -46,12 +45,7 @@ public class MyWebStorageManager: ChannelDelegate {
public static func fetchDataRecords(dataTypes: Set<String>, result: @escaping FlutterResult) {
var recordList: [[String: Any?]] = []
guard let websiteDataStore = MyWebStorageManager.websiteDataStore else {
result(recordList)
return
}
websiteDataStore.fetchDataRecords(ofTypes: dataTypes) { (data) in
MyWebStorageManager.websiteDataStore.fetchDataRecords(ofTypes: dataTypes) { (data) in
for record in data {
recordList.append([
"displayName": record.displayName,
@ -67,12 +61,7 @@ public class MyWebStorageManager: ChannelDelegate {
public static func removeDataFor(dataTypes: Set<String>, recordList: [[String: Any?]], result: @escaping FlutterResult) {
var records: [WKWebsiteDataRecord] = []
guard let websiteDataStore = MyWebStorageManager.websiteDataStore else {
result(false)
return
}
websiteDataStore.fetchDataRecords(ofTypes: dataTypes) { (data) in
MyWebStorageManager.websiteDataStore.fetchDataRecords(ofTypes: dataTypes) { (data) in
for record in data {
for r in recordList {
let displayName = r["displayName"] as! String
@ -89,21 +78,15 @@ public class MyWebStorageManager: ChannelDelegate {
}
public static func removeDataModifiedSince(dataTypes: Set<String>, timestamp: Int64, result: @escaping FlutterResult) {
guard let websiteDataStore = MyWebStorageManager.websiteDataStore else {
result(false)
return
}
let date = NSDate(timeIntervalSince1970: TimeInterval(timestamp))
websiteDataStore.removeData(ofTypes: dataTypes, modifiedSince: date as Date) {
MyWebStorageManager.websiteDataStore.removeData(ofTypes: dataTypes, modifiedSince: date as Date) {
result(true)
}
}
public override func dispose() {
super.dispose()
MyWebStorageManager.registrar = nil
MyWebStorageManager.websiteDataStore = nil
plugin = nil
}
deinit {

View File

@ -10,11 +10,11 @@ import FlutterMacOS
public class PlatformUtil: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_platformutil"
static var registrar: FlutterPluginRegistrar?
var plugin: InAppWebViewFlutterPlugin?
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: PlatformUtil.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger))
InAppWebViewStatic.registrar = registrar
init(plugin: InAppWebViewFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: PlatformUtil.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -58,7 +58,7 @@ public class PlatformUtil: ChannelDelegate {
public override func dispose() {
super.dispose()
PlatformUtil.registrar = nil
plugin = nil
}
deinit {

View File

@ -18,6 +18,7 @@ public enum PrintJobState: Int {
public class PrintJobController : NSObject, Disposable {
static let METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_printjobcontroller_"
var id: String
var registrar: FlutterPluginRegistrar?
var job: NSPrintOperation?
var settings: PrintJobSettings?
var channelDelegate: PrintJobChannelDelegate?
@ -29,13 +30,14 @@ public class PrintJobController : NSObject, Disposable {
_ success: Bool,
_ contextInfo: UnsafeMutableRawPointer?) -> Void
public init(id: String, job: NSPrintOperation? = nil, settings: PrintJobSettings? = nil) {
public init(registrar: FlutterPluginRegistrar, id: String, job: NSPrintOperation? = nil, settings: PrintJobSettings? = nil) {
self.id = id
self.registrar = registrar
super.init()
self.job = job
self.settings = settings
let channel = FlutterMethodChannel(name: PrintJobController.METHOD_CHANNEL_NAME_PREFIX + id,
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger)
binaryMessenger: registrar.messenger)
self.channelDelegate = PrintJobChannelDelegate(printJobController: self, channel: channel)
}
@ -83,5 +85,6 @@ public class PrintJobController : NSObject, Disposable {
completionHandler = nil
job = nil
PrintJobManager.jobs[id] = nil
registrar = nil
}
}

View File

@ -1,86 +0,0 @@
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
import FlutterMacOS
import AppKit
import WebKit
import Foundation
import AVFoundation
import SafariServices
public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
static var instance: SwiftFlutterPlugin?
var registrar: FlutterPluginRegistrar?
var platformUtil: PlatformUtil?
var inAppWebViewStatic: InAppWebViewStatic?
var myCookieManager: Any?
var myWebStorageManager: MyWebStorageManager?
var credentialDatabase: CredentialDatabase?
var inAppBrowserManager: InAppBrowserManager?
var headlessInAppWebViewManager: HeadlessInAppWebViewManager?
var webAuthenticationSessionManager: WebAuthenticationSessionManager?
// var printJobManager: PrintJobManager?
var webViewControllers: [String: InAppBrowserWebViewController?] = [:]
var safariViewControllers: [String: Any?] = [:]
public init(with registrar: FlutterPluginRegistrar) {
super.init()
self.registrar = registrar
registrar.register(FlutterWebViewFactory(registrar: registrar) as FlutterPlatformViewFactory, withId: FlutterWebViewFactory.VIEW_TYPE_ID)
platformUtil = PlatformUtil(registrar: registrar)
inAppBrowserManager = InAppBrowserManager(registrar: registrar)
headlessInAppWebViewManager = HeadlessInAppWebViewManager(registrar: registrar)
inAppWebViewStatic = InAppWebViewStatic(registrar: registrar)
credentialDatabase = CredentialDatabase(registrar: registrar)
if #available(macOS 10.13, *) {
myCookieManager = MyCookieManager(registrar: registrar)
}
myWebStorageManager = MyWebStorageManager(registrar: registrar)
webAuthenticationSessionManager = WebAuthenticationSessionManager(registrar: registrar)
// printJobManager = PrintJobManager()
}
public static func register(with registrar: FlutterPluginRegistrar) {
SwiftFlutterPlugin.instance = SwiftFlutterPlugin(with: registrar)
}
public func detachFromEngine(for registrar: FlutterPluginRegistrar) {
platformUtil?.dispose()
platformUtil = nil
inAppBrowserManager?.dispose()
inAppBrowserManager = nil
headlessInAppWebViewManager?.dispose()
headlessInAppWebViewManager = nil
inAppWebViewStatic?.dispose()
inAppWebViewStatic = nil
credentialDatabase?.dispose()
credentialDatabase = nil
if #available(macOS 10.13, *) {
(myCookieManager as! MyCookieManager?)?.dispose()
myCookieManager = nil
}
myWebStorageManager?.dispose()
myWebStorageManager = nil
webAuthenticationSessionManager?.dispose()
webAuthenticationSessionManager = nil
// printJobManager?.dispose()
// printJobManager = nil
}
}

View File

@ -13,6 +13,7 @@ import FlutterMacOS
public class WebAuthenticationSession : NSObject, ASWebAuthenticationPresentationContextProviding, Disposable {
static let METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_webauthenticationsession_"
var id: String
var plugin: InAppWebViewFlutterPlugin?
var url: URL
var callbackURLScheme: String?
var settings: WebAuthenticationSessionSettings
@ -20,8 +21,9 @@ public class WebAuthenticationSession : NSObject, ASWebAuthenticationPresentatio
var channelDelegate: WebAuthenticationSessionChannelDelegate?
private var _canStart = true
public init(id: String, url: URL, callbackURLScheme: String?, settings: WebAuthenticationSessionSettings) {
public init(plugin: InAppWebViewFlutterPlugin, id: String, url: URL, callbackURLScheme: String?, settings: WebAuthenticationSessionSettings) {
self.id = id
self.plugin = plugin
self.url = url
self.settings = settings
super.init()
@ -32,7 +34,7 @@ public class WebAuthenticationSession : NSObject, ASWebAuthenticationPresentatio
self.session = session
}
let channel = FlutterMethodChannel(name: WebAuthenticationSession.METHOD_CHANNEL_NAME_PREFIX + id,
binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger)
binaryMessenger: plugin.registrar!.messenger)
self.channelDelegate = WebAuthenticationSessionChannelDelegate(webAuthenticationSession: self, channel: channel)
}
@ -90,6 +92,7 @@ public class WebAuthenticationSession : NSObject, ASWebAuthenticationPresentatio
channelDelegate = nil
session = nil
WebAuthenticationSessionManager.sessions[id] = nil
plugin = nil
}
deinit {

View File

@ -14,12 +14,12 @@ import SafariServices
public class WebAuthenticationSessionManager: ChannelDelegate {
static let METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_webauthenticationsession"
static var registrar: FlutterPluginRegistrar?
var plugin: InAppWebViewFlutterPlugin?
static var sessions: [String: WebAuthenticationSession?] = [:]
init(registrar: FlutterPluginRegistrar) {
super.init(channel: FlutterMethodChannel(name: WebAuthenticationSessionManager.METHOD_CHANNEL_NAME, binaryMessenger: registrar.messenger))
WebAuthenticationSessionManager.registrar = registrar
init(plugin: InAppWebViewFlutterPlugin) {
super.init(channel: FlutterMethodChannel(name: WebAuthenticationSessionManager.METHOD_CHANNEL_NAME, binaryMessenger: plugin.registrar!.messenger))
self.plugin = plugin
}
public override func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@ -47,11 +47,11 @@ public class WebAuthenticationSessionManager: ChannelDelegate {
}
public func create(id: String, url: String, callbackURLScheme: String?, settings: [String: Any?], result: @escaping FlutterResult) {
if #available(macOS 10.15, *) {
if #available(macOS 10.15, *), let plugin = plugin {
let sessionUrl = URL(string: url) ?? URL(string: "about:blank")!
let initialSettings = WebAuthenticationSessionSettings()
let _ = initialSettings.parse(settings: settings)
let session = WebAuthenticationSession(id: id, url: sessionUrl, callbackURLScheme: callbackURLScheme, settings: initialSettings)
let session = WebAuthenticationSession(plugin: plugin, id: id, url: sessionUrl, callbackURLScheme: callbackURLScheme, settings: initialSettings)
session.prepare()
WebAuthenticationSessionManager.sessions[id] = session
result(true)
@ -63,13 +63,13 @@ public class WebAuthenticationSessionManager: ChannelDelegate {
public override func dispose() {
super.dispose()
WebAuthenticationSessionManager.registrar = nil
let sessions = WebAuthenticationSessionManager.sessions.values
sessions.forEach { (session: WebAuthenticationSession?) in
session?.cancel()
session?.dispose()
}
WebAuthenticationSessionManager.sessions.removeAll()
plugin = nil
}
deinit {