Managed iOS native detachFromEngine flutter plugin event and updated dispose methods, Updated Android native HeadlessInAppWebViewManager.dispose and HeadlessInAppWebView.dispose methods
This commit is contained in:
parent
d1e4dc55d0
commit
2d31a2f58b
|
@ -1,3 +1,8 @@
|
|||
## 5.4.1
|
||||
|
||||
- Managed iOS native `detachFromEngine` flutter plugin event and updated `dispose` methods
|
||||
- Updated Android native `HeadlessInAppWebViewManager.dispose` and `HeadlessInAppWebView.dispose` methods
|
||||
|
||||
## 5.4.0+3
|
||||
|
||||
- Fixed Android error in some cases when calling `setServiceWorkerClient` java method on `ServiceWorkerManager` initialization
|
||||
|
|
|
@ -110,12 +110,16 @@ public class HeadlessInAppWebView implements MethodChannel.MethodCallHandler {
|
|||
public void dispose() {
|
||||
channel.setMethodCallHandler(null);
|
||||
HeadlessInAppWebViewManager.webViews.remove(id);
|
||||
ViewGroup contentView = (ViewGroup) plugin.activity.findViewById(android.R.id.content);
|
||||
ViewGroup mainView = (ViewGroup) (contentView).getChildAt(0);
|
||||
if (mainView != null) {
|
||||
mainView.removeView(flutterWebView.getView());
|
||||
if (plugin != null) {
|
||||
ViewGroup contentView = (ViewGroup) plugin.activity.findViewById(android.R.id.content);
|
||||
ViewGroup mainView = (ViewGroup) (contentView).getChildAt(0);
|
||||
if (mainView != null && flutterWebView != null) {
|
||||
mainView.removeView(flutterWebView.getView());
|
||||
}
|
||||
}
|
||||
if (flutterWebView != null) {
|
||||
flutterWebView.dispose();
|
||||
}
|
||||
flutterWebView.dispose();
|
||||
flutterWebView = null;
|
||||
plugin = null;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,9 @@ import androidx.annotation.Nullable;
|
|||
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
|
||||
import com.pichillilorenzo.flutter_inappwebview.in_app_webview.FlutterWebView;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
|
@ -77,6 +79,10 @@ public class HeadlessInAppWebViewManager implements MethodChannel.MethodCallHand
|
|||
|
||||
public void dispose() {
|
||||
channel.setMethodCallHandler(null);
|
||||
Collection<HeadlessInAppWebView> headlessInAppWebViews = webViews.values();
|
||||
for (HeadlessInAppWebView headlessInAppWebView : headlessInAppWebViews) {
|
||||
headlessInAppWebView.dispose();
|
||||
}
|
||||
webViews.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,11 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
|||
switch call.method {
|
||||
case "getAllAuthCredentials":
|
||||
var allCredentials: [[String: Any?]] = []
|
||||
for (protectionSpace, credentials) in CredentialDatabase.credentialStore!.allCredentials {
|
||||
guard let credentialStore = CredentialDatabase.credentialStore else {
|
||||
result(allCredentials)
|
||||
return
|
||||
}
|
||||
for (protectionSpace, credentials) in credentialStore.allCredentials {
|
||||
var crendentials: [[String: Any?]] = []
|
||||
for c in credentials {
|
||||
let credential: [String: Any?] = c.value.toMap()
|
||||
|
@ -43,10 +47,17 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
|||
"credentials": crendentials
|
||||
]
|
||||
allCredentials.append(dict)
|
||||
} }
|
||||
}
|
||||
}
|
||||
result(allCredentials)
|
||||
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
|
||||
|
@ -54,9 +65,8 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
|||
if let r = realm, r.isEmpty {
|
||||
realm = nil
|
||||
}
|
||||
var crendentials: [[String: Any?]] = []
|
||||
|
||||
for (protectionSpace, credentials) in CredentialDatabase.credentialStore!.allCredentials {
|
||||
for (protectionSpace, credentials) in credentialStore.allCredentials {
|
||||
if protectionSpace.host == host && protectionSpace.realm == realm &&
|
||||
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
|
||||
for c in credentials {
|
||||
|
@ -68,6 +78,11 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
|||
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
|
||||
|
@ -78,11 +93,17 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
|||
let username = arguments!["username"] as! String
|
||||
let password = arguments!["password"] as! String
|
||||
let credential = URLCredential(user: username, password: password, persistence: .permanent)
|
||||
CredentialDatabase.credentialStore!.set(credential,
|
||||
for: URLProtectionSpace(host: host, port: urlPort, protocol: urlProtocol, realm: realm, authenticationMethod: NSURLAuthenticationMethodHTTPBasic))
|
||||
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
|
||||
|
@ -96,7 +117,7 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
|||
var credential: URLCredential? = nil;
|
||||
var protectionSpaceCredential: URLProtectionSpace? = nil
|
||||
|
||||
for (protectionSpace, credentials) in CredentialDatabase.credentialStore!.allCredentials {
|
||||
for (protectionSpace, credentials) in credentialStore.allCredentials {
|
||||
if protectionSpace.host == host && protectionSpace.realm == realm &&
|
||||
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
|
||||
for c in credentials {
|
||||
|
@ -113,12 +134,17 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
|||
}
|
||||
|
||||
if let c = credential, let protectionSpace = protectionSpaceCredential {
|
||||
CredentialDatabase.credentialStore!.remove(c, for: protectionSpace)
|
||||
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
|
||||
|
@ -130,7 +156,7 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
|||
var credentialsToRemove: [URLCredential] = [];
|
||||
var protectionSpaceCredential: URLProtectionSpace? = nil
|
||||
|
||||
for (protectionSpace, credentials) in CredentialDatabase.credentialStore!.allCredentials {
|
||||
for (protectionSpace, credentials) in credentialStore.allCredentials {
|
||||
if protectionSpace.host == host && protectionSpace.realm == realm &&
|
||||
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
|
||||
protectionSpaceCredential = protectionSpace
|
||||
|
@ -145,16 +171,21 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
|||
|
||||
if let protectionSpace = protectionSpaceCredential {
|
||||
for credential in credentialsToRemove {
|
||||
CredentialDatabase.credentialStore!.remove(credential, for: protectionSpace)
|
||||
credentialStore.remove(credential, for: protectionSpace)
|
||||
}
|
||||
}
|
||||
|
||||
result(true)
|
||||
break
|
||||
case "clearAllAuthCredentials":
|
||||
for (protectionSpace, credentials) in CredentialDatabase.credentialStore!.allCredentials {
|
||||
guard let credentialStore = CredentialDatabase.credentialStore else {
|
||||
result(false)
|
||||
return
|
||||
}
|
||||
|
||||
for (protectionSpace, credentials) in credentialStore.allCredentials {
|
||||
for credential in credentials {
|
||||
CredentialDatabase.credentialStore!.remove(credential.value, for: protectionSpace)
|
||||
credentialStore.remove(credential.value, for: protectionSpace)
|
||||
}
|
||||
}
|
||||
result(true)
|
||||
|
@ -164,4 +195,11 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
|||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func dispose() {
|
||||
CredentialDatabase.channel?.setMethodCallHandler(nil)
|
||||
CredentialDatabase.channel = nil
|
||||
CredentialDatabase.registrar = nil
|
||||
CredentialDatabase.credentialStore = nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,4 +57,15 @@ public class HeadlessInAppWebViewManager: NSObject, FlutterPlugin {
|
|||
headlessInAppWebView.onWebViewCreated()
|
||||
flutterWebView.makeInitialLoad(params: params as NSDictionary)
|
||||
}
|
||||
|
||||
public func dispose() {
|
||||
HeadlessInAppWebViewManager.channel?.setMethodCallHandler(nil)
|
||||
HeadlessInAppWebViewManager.channel = nil
|
||||
HeadlessInAppWebViewManager.registrar = nil
|
||||
let headlessWebViews = HeadlessInAppWebViewManager.webViews.values
|
||||
headlessWebViews.forEach { (headlessWebView: HeadlessInAppWebView) in
|
||||
headlessWebView.dispose()
|
||||
}
|
||||
HeadlessInAppWebViewManager.webViews.removeAll()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,4 +140,10 @@ public class InAppBrowserManager: NSObject, FlutterPlugin {
|
|||
}
|
||||
result(true)
|
||||
}
|
||||
|
||||
public func dispose() {
|
||||
InAppBrowserManager.channel?.setMethodCallHandler(nil)
|
||||
InAppBrowserManager.channel = nil
|
||||
InAppBrowserManager.registrar = nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -182,6 +182,7 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
|
|||
|
||||
deinit {
|
||||
print("InAppBrowserWebViewController - dealloc")
|
||||
dispose()
|
||||
}
|
||||
|
||||
public override func viewDidDisappear(_ animated: Bool) {
|
||||
|
@ -550,7 +551,10 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
|
|||
}
|
||||
|
||||
public func dispose() {
|
||||
webView.dispose()
|
||||
onExit()
|
||||
channel?.setMethodCallHandler(nil)
|
||||
channel = nil
|
||||
webView?.dispose()
|
||||
webView = nil
|
||||
view = nil
|
||||
if previousStatusBarStyle != -1 {
|
||||
|
@ -563,18 +567,15 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
|
|||
backButton.target = nil
|
||||
reloadButton.target = nil
|
||||
shareButton.target = nil
|
||||
onExit()
|
||||
channel?.setMethodCallHandler(nil)
|
||||
channel = nil
|
||||
methodCallDelegate?.webView = nil
|
||||
methodCallDelegate = nil
|
||||
}
|
||||
|
||||
public func onBrowserCreated() {
|
||||
channel!.invokeMethod("onBrowserCreated", arguments: [])
|
||||
channel?.invokeMethod("onBrowserCreated", arguments: [])
|
||||
}
|
||||
|
||||
public func onExit() {
|
||||
channel!.invokeMethod("onExit", arguments: [])
|
||||
channel?.invokeMethod("onExit", arguments: [])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,7 +164,8 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
|||
|
||||
func dispose() {
|
||||
channel?.setMethodCallHandler(nil)
|
||||
methodCallDelegate?.webView = nil
|
||||
channel = nil
|
||||
methodCallDelegate?.dispose()
|
||||
methodCallDelegate = nil
|
||||
webView?.dispose()
|
||||
webView = nil
|
||||
|
|
|
@ -1673,8 +1673,8 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
|||
completionHandler(.useCredential, credential)
|
||||
break
|
||||
case 2:
|
||||
if InAppWebView.credentialsProposed.count == 0 {
|
||||
for (protectionSpace, credentials) in CredentialDatabase.credentialStore!.allCredentials {
|
||||
if InAppWebView.credentialsProposed.count == 0, let credentialStore = CredentialDatabase.credentialStore {
|
||||
for (protectionSpace, credentials) in credentialStore.allCredentials {
|
||||
if protectionSpace.host == host && protectionSpace.realm == realm &&
|
||||
protectionSpace.protocol == prot && protectionSpace.port == port {
|
||||
for credential in credentials {
|
||||
|
@ -2900,6 +2900,12 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
|
|||
}
|
||||
|
||||
public func dispose() {
|
||||
channel = nil
|
||||
removeObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress))
|
||||
removeObserver(self, forKeyPath: #keyPath(WKWebView.url))
|
||||
removeObserver(self, forKeyPath: #keyPath(WKWebView.title))
|
||||
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.contentOffset))
|
||||
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.zoomScale))
|
||||
resumeTimers()
|
||||
stopLoading()
|
||||
disposeWebMessageChannels()
|
||||
|
@ -2920,15 +2926,10 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
|
|||
InAppWebView.windowWebViews.removeValue(forKey: wId)
|
||||
}
|
||||
configuration.userContentController.dispose(windowId: windowId)
|
||||
removeObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress))
|
||||
removeObserver(self, forKeyPath: #keyPath(WKWebView.url))
|
||||
removeObserver(self, forKeyPath: #keyPath(WKWebView.title))
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
for imp in customIMPs {
|
||||
imp_removeBlock(imp)
|
||||
}
|
||||
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.contentOffset))
|
||||
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.zoomScale))
|
||||
longPressRecognizer.removeTarget(self, action: #selector(longPressGestureDetected))
|
||||
longPressRecognizer.delegate = nil
|
||||
scrollView.removeGestureRecognizer(longPressRecognizer)
|
||||
|
@ -2945,7 +2946,6 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
|
|||
navigationDelegate = nil
|
||||
scrollView.delegate = nil
|
||||
isPausedTimersCompletionHandler = nil
|
||||
channel = nil
|
||||
SharedLastTouchPointTimestamp.removeValue(forKey: self)
|
||||
callAsyncJavaScriptBelowIOS14Results.removeAll()
|
||||
super.removeFromSuperview()
|
||||
|
|
|
@ -553,8 +553,12 @@ public class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
print("InAppWebViewMethodHandler - dealloc")
|
||||
public func dispose() {
|
||||
webView = nil
|
||||
}
|
||||
|
||||
deinit {
|
||||
print("InAppWebViewMethodHandler - dealloc")
|
||||
dispose()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,4 +72,12 @@ class InAppWebViewStatic: NSObject, FlutterPlugin {
|
|||
completionHandler(defaultUserAgent)
|
||||
}
|
||||
}
|
||||
|
||||
public func dispose() {
|
||||
InAppWebViewStatic.channel?.setMethodCallHandler(nil)
|
||||
InAppWebViewStatic.channel = nil
|
||||
InAppWebViewStatic.registrar = nil
|
||||
InAppWebViewStatic.webViewForUserAgent = nil
|
||||
InAppWebViewStatic.defaultUserAgent = nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,6 +100,11 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
|||
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
|
||||
|
@ -138,7 +143,7 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
|||
|
||||
let cookie = HTTPCookie(properties: properties)!
|
||||
|
||||
MyCookieManager.httpCookieStore!.setCookie(cookie, completionHandler: {() in
|
||||
httpCookieStore.setCookie(cookie, completionHandler: {() in
|
||||
result(true)
|
||||
})
|
||||
}
|
||||
|
@ -146,8 +151,13 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
|||
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 {
|
||||
MyCookieManager.httpCookieStore!.getAllCookies { (cookies) in
|
||||
httpCookieStore.getAllCookies { (cookies) in
|
||||
for cookie in cookies {
|
||||
if urlHost.hasSuffix(cookie.domain) || ".\(urlHost)".hasSuffix(cookie.domain) {
|
||||
var sameSite: String? = nil
|
||||
|
@ -189,7 +199,12 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
|||
public static func getAllCookies(result: @escaping FlutterResult) {
|
||||
var cookieList: [[String: Any?]] = []
|
||||
|
||||
MyCookieManager.httpCookieStore!.getAllCookies { (cookies) in
|
||||
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
|
||||
result(cookieList)
|
||||
return
|
||||
}
|
||||
|
||||
httpCookieStore.getAllCookies { (cookies) in
|
||||
for cookie in cookies {
|
||||
var sameSite: String? = nil
|
||||
if #available(iOS 13.0, *) {
|
||||
|
@ -221,7 +236,12 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
|||
}
|
||||
|
||||
public static func deleteCookie(url: String, name: String, domain: String, path: String, result: @escaping FlutterResult) {
|
||||
MyCookieManager.httpCookieStore!.getAllCookies { (cookies) in
|
||||
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
|
||||
result(false)
|
||||
return
|
||||
}
|
||||
|
||||
httpCookieStore.getAllCookies { (cookies) in
|
||||
for cookie in cookies {
|
||||
var originURL = ""
|
||||
if cookie.properties![.originURL] is String {
|
||||
|
@ -234,7 +254,7 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
|||
continue
|
||||
}
|
||||
if (cookie.domain == domain || cookie.domain == ".\(domain)" || ".\(cookie.domain)" == domain) && cookie.name == name && cookie.path == path {
|
||||
MyCookieManager.httpCookieStore!.delete(cookie, completionHandler: {
|
||||
httpCookieStore.delete(cookie, completionHandler: {
|
||||
result(true)
|
||||
})
|
||||
return
|
||||
|
@ -245,7 +265,12 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
|||
}
|
||||
|
||||
public static func deleteCookies(url: String, domain: String, path: String, result: @escaping FlutterResult) {
|
||||
MyCookieManager.httpCookieStore!.getAllCookies { (cookies) in
|
||||
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
|
||||
result(false)
|
||||
return
|
||||
}
|
||||
|
||||
httpCookieStore.getAllCookies { (cookies) in
|
||||
for cookie in cookies {
|
||||
var originURL = ""
|
||||
if cookie.properties![.originURL] is String {
|
||||
|
@ -258,7 +283,7 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
|||
continue
|
||||
}
|
||||
if (cookie.domain == domain || cookie.domain == ".\(domain)" || ".\(cookie.domain)" == domain) && cookie.path == path {
|
||||
MyCookieManager.httpCookieStore!.delete(cookie, completionHandler: nil)
|
||||
httpCookieStore.delete(cookie, completionHandler: nil)
|
||||
}
|
||||
}
|
||||
result(true)
|
||||
|
@ -272,4 +297,11 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
|||
result(true)
|
||||
})
|
||||
}
|
||||
|
||||
public func dispose() {
|
||||
MyCookieManager.channel?.setMethodCallHandler(nil)
|
||||
MyCookieManager.channel = nil
|
||||
MyCookieManager.registrar = nil
|
||||
MyCookieManager.httpCookieStore = nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,13 @@ class MyWebStorageManager: NSObject, FlutterPlugin {
|
|||
|
||||
public static func fetchDataRecords(dataTypes: Set<String>, result: @escaping FlutterResult) {
|
||||
var recordList: [[String: Any?]] = []
|
||||
MyWebStorageManager.websiteDataStore!.fetchDataRecords(ofTypes: dataTypes) { (data) in
|
||||
|
||||
guard let websiteDataStore = MyWebStorageManager.websiteDataStore else {
|
||||
result(recordList)
|
||||
return
|
||||
}
|
||||
|
||||
websiteDataStore.fetchDataRecords(ofTypes: dataTypes) { (data) in
|
||||
for record in data {
|
||||
recordList.append([
|
||||
"displayName": record.displayName,
|
||||
|
@ -68,7 +74,13 @@ class MyWebStorageManager: NSObject, FlutterPlugin {
|
|||
|
||||
public static func removeDataFor(dataTypes: Set<String>, recordList: [[String: Any?]], result: @escaping FlutterResult) {
|
||||
var records: [WKWebsiteDataRecord] = []
|
||||
MyWebStorageManager.websiteDataStore!.fetchDataRecords(ofTypes: dataTypes) { (data) in
|
||||
|
||||
guard let websiteDataStore = MyWebStorageManager.websiteDataStore else {
|
||||
result(false)
|
||||
return
|
||||
}
|
||||
|
||||
websiteDataStore.fetchDataRecords(ofTypes: dataTypes) { (data) in
|
||||
for record in data {
|
||||
for r in recordList {
|
||||
let displayName = r["displayName"] as! String
|
||||
|
@ -78,16 +90,28 @@ class MyWebStorageManager: NSObject, FlutterPlugin {
|
|||
}
|
||||
}
|
||||
}
|
||||
MyWebStorageManager.websiteDataStore!.removeData(ofTypes: dataTypes, for: records) {
|
||||
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))
|
||||
MyWebStorageManager.websiteDataStore!.removeData(ofTypes: dataTypes, modifiedSince: date as Date) {
|
||||
websiteDataStore.removeData(ofTypes: dataTypes, modifiedSince: date as Date) {
|
||||
result(true)
|
||||
}
|
||||
}
|
||||
|
||||
public func dispose() {
|
||||
MyWebStorageManager.channel?.setMethodCallHandler(nil)
|
||||
MyWebStorageManager.channel = nil
|
||||
MyWebStorageManager.registrar = nil
|
||||
MyWebStorageManager.websiteDataStore = nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,4 +60,10 @@ class PlatformUtil: NSObject, FlutterPlugin {
|
|||
formatter.timeZone = timezone
|
||||
return formatter.string(from: PlatformUtil.getDateFromMilliseconds(date: date))
|
||||
}
|
||||
|
||||
public func dispose() {
|
||||
PlatformUtil.channel?.setMethodCallHandler(nil)
|
||||
PlatformUtil.channel = nil
|
||||
PlatformUtil.registrar = nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,5 +109,6 @@ public class PullToRefreshControl : UIRefreshControl, FlutterPlugin {
|
|||
|
||||
deinit {
|
||||
print("PullToRefreshControl - dealloc")
|
||||
dispose()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,4 +91,10 @@ public class ChromeSafariBrowserManager: NSObject, FlutterPlugin {
|
|||
|
||||
result(FlutterError.init(code: "ChromeSafariBrowserManager", message: "SafariViewController is not available!", details: nil))
|
||||
}
|
||||
|
||||
public func dispose() {
|
||||
ChromeSafariBrowserManager.channel?.setMethodCallHandler(nil)
|
||||
ChromeSafariBrowserManager.channel = nil
|
||||
ChromeSafariBrowserManager.registrar = nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafa
|
|||
|
||||
deinit {
|
||||
print("SafariViewController - dealloc")
|
||||
dispose()
|
||||
}
|
||||
|
||||
public func prepareMethodChannel() {
|
||||
|
@ -123,20 +124,21 @@ public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafa
|
|||
// }
|
||||
|
||||
public func onChromeSafariBrowserOpened() {
|
||||
channel!.invokeMethod("onChromeSafariBrowserOpened", arguments: [])
|
||||
channel?.invokeMethod("onChromeSafariBrowserOpened", arguments: [])
|
||||
}
|
||||
|
||||
public func onChromeSafariBrowserCompletedInitialLoad() {
|
||||
channel!.invokeMethod("onChromeSafariBrowserCompletedInitialLoad", arguments: [])
|
||||
channel?.invokeMethod("onChromeSafariBrowserCompletedInitialLoad", arguments: [])
|
||||
}
|
||||
|
||||
public func onChromeSafariBrowserClosed() {
|
||||
channel!.invokeMethod("onChromeSafariBrowserClosed", arguments: [])
|
||||
channel?.invokeMethod("onChromeSafariBrowserClosed", arguments: [])
|
||||
}
|
||||
|
||||
public func dispose() {
|
||||
channel?.setMethodCallHandler(nil)
|
||||
channel = nil
|
||||
delegate = nil
|
||||
channel!.setMethodCallHandler(nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,7 +182,12 @@ class CustomUIActivity : UIActivity {
|
|||
}
|
||||
|
||||
override func perform() {
|
||||
let channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_chromesafaribrowser_" + viewId, binaryMessenger: SwiftFlutterPlugin.instance!.registrar!.messenger())
|
||||
guard let registrar = SwiftFlutterPlugin.instance?.registrar else {
|
||||
return
|
||||
}
|
||||
|
||||
let channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_chromesafaribrowser_" + viewId,
|
||||
binaryMessenger: registrar.messenger())
|
||||
|
||||
let arguments: [String: Any?] = [
|
||||
"url": url.absoluteString,
|
||||
|
|
|
@ -49,16 +49,39 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
|||
headlessInAppWebViewManager = HeadlessInAppWebViewManager(registrar: registrar)
|
||||
chromeSafariBrowserManager = ChromeSafariBrowserManager(registrar: registrar)
|
||||
inAppWebViewStatic = InAppWebViewStatic(registrar: registrar)
|
||||
credentialDatabase = CredentialDatabase(registrar: registrar)
|
||||
if #available(iOS 11.0, *) {
|
||||
myCookieManager = MyCookieManager(registrar: registrar)
|
||||
}
|
||||
if #available(iOS 9.0, *) {
|
||||
myWebStorageManager = MyWebStorageManager(registrar: registrar)
|
||||
}
|
||||
credentialDatabase = CredentialDatabase(registrar: registrar)
|
||||
}
|
||||
|
||||
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
|
||||
chromeSafariBrowserManager?.dispose()
|
||||
chromeSafariBrowserManager = nil
|
||||
inAppWebViewStatic?.dispose()
|
||||
inAppWebViewStatic = nil
|
||||
credentialDatabase?.dispose()
|
||||
credentialDatabase = nil
|
||||
if #available(iOS 11.0, *) {
|
||||
(myCookieManager as! MyCookieManager?)?.dispose()
|
||||
myCookieManager = nil
|
||||
}
|
||||
if #available(iOS 9.0, *) {
|
||||
(myWebStorageManager as! MyWebStorageManager?)?.dispose()
|
||||
myWebStorageManager = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ extension WKUserContentController {
|
|||
var contentWorlds: Set<WKContentWorld> {
|
||||
get {
|
||||
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
||||
return WKUserContentController._contentWorlds[tmpAddress]!
|
||||
return WKUserContentController._contentWorlds[tmpAddress] ?? []
|
||||
}
|
||||
set(newValue) {
|
||||
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
||||
|
@ -33,7 +33,7 @@ extension WKUserContentController {
|
|||
var userOnlyScripts: [WKUserScriptInjectionTime:OrderedSet<UserScript>] {
|
||||
get {
|
||||
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
||||
return WKUserContentController._userOnlyScripts[tmpAddress]!
|
||||
return WKUserContentController._userOnlyScripts[tmpAddress] ?? [:]
|
||||
}
|
||||
set(newValue) {
|
||||
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
||||
|
@ -45,7 +45,7 @@ extension WKUserContentController {
|
|||
var pluginScripts: [WKUserScriptInjectionTime:OrderedSet<PluginScript>] {
|
||||
get {
|
||||
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
||||
return WKUserContentController._pluginScripts[tmpAddress]!
|
||||
return WKUserContentController._pluginScripts[tmpAddress] ?? [:]
|
||||
}
|
||||
set(newValue) {
|
||||
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
||||
|
|
|
@ -23,5 +23,6 @@ public class WebMessage : NSObject {
|
|||
|
||||
deinit {
|
||||
print("WebMessage - dealloc")
|
||||
dispose()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,6 +126,7 @@ public class WebMessageChannel : FlutterMethodCallDelegate {
|
|||
|
||||
public func dispose() {
|
||||
channel?.setMethodCallHandler(nil)
|
||||
channel = nil
|
||||
for port in ports {
|
||||
port.dispose()
|
||||
}
|
||||
|
@ -140,11 +141,11 @@ public class WebMessageChannel : FlutterMethodCallDelegate {
|
|||
}
|
||||
})();
|
||||
""")
|
||||
channel = nil
|
||||
webView = nil
|
||||
}
|
||||
|
||||
deinit {
|
||||
print("WebMessageChannel - dealloc")
|
||||
dispose()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -222,5 +222,6 @@ public class WebMessageListener : FlutterMethodCallDelegate {
|
|||
|
||||
deinit {
|
||||
print("WebMessageListener - dealloc")
|
||||
dispose()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,5 +118,6 @@ public class WebMessagePort : NSObject {
|
|||
|
||||
deinit {
|
||||
print("WebMessagePort - dealloc")
|
||||
dispose()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ var SharedLastTouchPointTimestamp: [InAppWebView: Int64] = [:]
|
|||
|
||||
public class Util {
|
||||
public static func getUrlAsset(assetFilePath: String) throws -> URL {
|
||||
let key = SwiftFlutterPlugin.instance!.registrar!.lookupKey(forAsset: assetFilePath)
|
||||
let key = SwiftFlutterPlugin.instance?.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)
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ public class Util {
|
|||
}
|
||||
|
||||
public static func getAbsPathAsset(assetFilePath: String) throws -> String {
|
||||
let key = SwiftFlutterPlugin.instance!.registrar!.lookupKey(forAsset: assetFilePath)
|
||||
let key = SwiftFlutterPlugin.instance?.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)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: flutter_inappwebview
|
||||
description: A Flutter plugin that allows you to add an inline webview, to use an headless webview, and to open an in-app browser window.
|
||||
version: 5.4.0+3
|
||||
version: 5.4.1
|
||||
homepage: https://github.com/pichillilorenzo/flutter_inappwebview
|
||||
|
||||
environment:
|
||||
|
|
Loading…
Reference in New Issue