merge
This commit is contained in:
commit
68305a365b
|
@ -6,6 +6,11 @@
|
||||||
- Added support for `onPermissionRequest` event on iOS 15.0+
|
- Added support for `onPermissionRequest` event on iOS 15.0+
|
||||||
- Updated `getMetaThemeColor` on iOS 15.0+
|
- Updated `getMetaThemeColor` on iOS 15.0+
|
||||||
|
|
||||||
|
## 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
|
## 5.4.0+3
|
||||||
|
|
||||||
- Fixed Android error in some cases when calling `setServiceWorkerClient` java method on `ServiceWorkerManager` initialization
|
- 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() {
|
public void dispose() {
|
||||||
channel.setMethodCallHandler(null);
|
channel.setMethodCallHandler(null);
|
||||||
HeadlessInAppWebViewManager.webViews.remove(id);
|
HeadlessInAppWebViewManager.webViews.remove(id);
|
||||||
ViewGroup contentView = (ViewGroup) plugin.activity.findViewById(android.R.id.content);
|
if (plugin != null) {
|
||||||
ViewGroup mainView = (ViewGroup) (contentView).getChildAt(0);
|
ViewGroup contentView = (ViewGroup) plugin.activity.findViewById(android.R.id.content);
|
||||||
if (mainView != null) {
|
ViewGroup mainView = (ViewGroup) (contentView).getChildAt(0);
|
||||||
mainView.removeView(flutterWebView.getView());
|
if (mainView != null && flutterWebView != null) {
|
||||||
|
mainView.removeView(flutterWebView.getView());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flutterWebView != null) {
|
||||||
|
flutterWebView.dispose();
|
||||||
}
|
}
|
||||||
flutterWebView.dispose();
|
|
||||||
flutterWebView = null;
|
flutterWebView = null;
|
||||||
plugin = null;
|
plugin = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,9 @@ import androidx.annotation.Nullable;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
|
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.in_app_webview.FlutterWebView;
|
import com.pichillilorenzo.flutter_inappwebview.in_app_webview.FlutterWebView;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import io.flutter.plugin.common.MethodCall;
|
import io.flutter.plugin.common.MethodCall;
|
||||||
|
@ -77,6 +79,10 @@ public class HeadlessInAppWebViewManager implements MethodChannel.MethodCallHand
|
||||||
|
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
channel.setMethodCallHandler(null);
|
channel.setMethodCallHandler(null);
|
||||||
|
Collection<HeadlessInAppWebView> headlessInAppWebViews = webViews.values();
|
||||||
|
for (HeadlessInAppWebView headlessInAppWebView : headlessInAppWebViews) {
|
||||||
|
headlessInAppWebView.dispose();
|
||||||
|
}
|
||||||
webViews.clear();
|
webViews.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,11 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
||||||
switch call.method {
|
switch call.method {
|
||||||
case "getAllAuthCredentials":
|
case "getAllAuthCredentials":
|
||||||
var allCredentials: [[String: Any?]] = []
|
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?]] = []
|
var crendentials: [[String: Any?]] = []
|
||||||
for c in credentials {
|
for c in credentials {
|
||||||
let credential: [String: Any?] = c.value.toMap()
|
let credential: [String: Any?] = c.value.toMap()
|
||||||
|
@ -43,10 +47,17 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
||||||
"credentials": crendentials
|
"credentials": crendentials
|
||||||
]
|
]
|
||||||
allCredentials.append(dict)
|
allCredentials.append(dict)
|
||||||
} }
|
}
|
||||||
|
}
|
||||||
result(allCredentials)
|
result(allCredentials)
|
||||||
break
|
break
|
||||||
case "getHttpAuthCredentials":
|
case "getHttpAuthCredentials":
|
||||||
|
var crendentials: [[String: Any?]] = []
|
||||||
|
guard let credentialStore = CredentialDatabase.credentialStore else {
|
||||||
|
result(crendentials)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let host = arguments!["host"] as! String
|
let host = arguments!["host"] as! String
|
||||||
let urlProtocol = arguments!["protocol"] as? String
|
let urlProtocol = arguments!["protocol"] as? String
|
||||||
let urlPort = arguments!["port"] as? Int ?? 0
|
let urlPort = arguments!["port"] as? Int ?? 0
|
||||||
|
@ -54,9 +65,8 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
||||||
if let r = realm, r.isEmpty {
|
if let r = realm, r.isEmpty {
|
||||||
realm = nil
|
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 &&
|
if protectionSpace.host == host && protectionSpace.realm == realm &&
|
||||||
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
|
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
|
||||||
for c in credentials {
|
for c in credentials {
|
||||||
|
@ -68,6 +78,11 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
||||||
result(crendentials)
|
result(crendentials)
|
||||||
break
|
break
|
||||||
case "setHttpAuthCredential":
|
case "setHttpAuthCredential":
|
||||||
|
guard let credentialStore = CredentialDatabase.credentialStore else {
|
||||||
|
result(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let host = arguments!["host"] as! String
|
let host = arguments!["host"] as! String
|
||||||
let urlProtocol = arguments!["protocol"] as? String
|
let urlProtocol = arguments!["protocol"] as? String
|
||||||
let urlPort = arguments!["port"] as? Int ?? 0
|
let urlPort = arguments!["port"] as? Int ?? 0
|
||||||
|
@ -78,11 +93,17 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
||||||
let username = arguments!["username"] as! String
|
let username = arguments!["username"] as! String
|
||||||
let password = arguments!["password"] as! String
|
let password = arguments!["password"] as! String
|
||||||
let credential = URLCredential(user: username, password: password, persistence: .permanent)
|
let credential = URLCredential(user: username, password: password, persistence: .permanent)
|
||||||
CredentialDatabase.credentialStore!.set(credential,
|
credentialStore.set(credential,
|
||||||
for: URLProtectionSpace(host: host, port: urlPort, protocol: urlProtocol, realm: realm, authenticationMethod: NSURLAuthenticationMethodHTTPBasic))
|
for: URLProtectionSpace(host: host, port: urlPort, protocol: urlProtocol,
|
||||||
|
realm: realm, authenticationMethod: NSURLAuthenticationMethodHTTPBasic))
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
case "removeHttpAuthCredential":
|
case "removeHttpAuthCredential":
|
||||||
|
guard let credentialStore = CredentialDatabase.credentialStore else {
|
||||||
|
result(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let host = arguments!["host"] as! String
|
let host = arguments!["host"] as! String
|
||||||
let urlProtocol = arguments!["protocol"] as? String
|
let urlProtocol = arguments!["protocol"] as? String
|
||||||
let urlPort = arguments!["port"] as? Int ?? 0
|
let urlPort = arguments!["port"] as? Int ?? 0
|
||||||
|
@ -96,7 +117,7 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
||||||
var credential: URLCredential? = nil;
|
var credential: URLCredential? = nil;
|
||||||
var protectionSpaceCredential: URLProtectionSpace? = 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 &&
|
if protectionSpace.host == host && protectionSpace.realm == realm &&
|
||||||
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
|
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
|
||||||
for c in credentials {
|
for c in credentials {
|
||||||
|
@ -113,12 +134,17 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let c = credential, let protectionSpace = protectionSpaceCredential {
|
if let c = credential, let protectionSpace = protectionSpaceCredential {
|
||||||
CredentialDatabase.credentialStore!.remove(c, for: protectionSpace)
|
credentialStore.remove(c, for: protectionSpace)
|
||||||
}
|
}
|
||||||
|
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
case "removeHttpAuthCredentials":
|
case "removeHttpAuthCredentials":
|
||||||
|
guard let credentialStore = CredentialDatabase.credentialStore else {
|
||||||
|
result(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let host = arguments!["host"] as! String
|
let host = arguments!["host"] as! String
|
||||||
let urlProtocol = arguments!["protocol"] as? String
|
let urlProtocol = arguments!["protocol"] as? String
|
||||||
let urlPort = arguments!["port"] as? Int ?? 0
|
let urlPort = arguments!["port"] as? Int ?? 0
|
||||||
|
@ -130,7 +156,7 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
||||||
var credentialsToRemove: [URLCredential] = [];
|
var credentialsToRemove: [URLCredential] = [];
|
||||||
var protectionSpaceCredential: URLProtectionSpace? = 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 &&
|
if protectionSpace.host == host && protectionSpace.realm == realm &&
|
||||||
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
|
protectionSpace.protocol == urlProtocol && protectionSpace.port == urlPort {
|
||||||
protectionSpaceCredential = protectionSpace
|
protectionSpaceCredential = protectionSpace
|
||||||
|
@ -145,16 +171,21 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
||||||
|
|
||||||
if let protectionSpace = protectionSpaceCredential {
|
if let protectionSpace = protectionSpaceCredential {
|
||||||
for credential in credentialsToRemove {
|
for credential in credentialsToRemove {
|
||||||
CredentialDatabase.credentialStore!.remove(credential, for: protectionSpace)
|
credentialStore.remove(credential, for: protectionSpace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result(true)
|
result(true)
|
||||||
break
|
break
|
||||||
case "clearAllAuthCredentials":
|
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 {
|
for credential in credentials {
|
||||||
CredentialDatabase.credentialStore!.remove(credential.value, for: protectionSpace)
|
credentialStore.remove(credential.value, for: protectionSpace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result(true)
|
result(true)
|
||||||
|
@ -164,4 +195,11 @@ class CredentialDatabase: NSObject, FlutterPlugin {
|
||||||
break
|
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()
|
headlessInAppWebView.onWebViewCreated()
|
||||||
flutterWebView.makeInitialLoad(params: params as NSDictionary)
|
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)
|
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 {
|
deinit {
|
||||||
print("InAppBrowserWebViewController - dealloc")
|
print("InAppBrowserWebViewController - dealloc")
|
||||||
|
dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func viewDidDisappear(_ animated: Bool) {
|
public override func viewDidDisappear(_ animated: Bool) {
|
||||||
|
@ -550,7 +551,10 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
|
||||||
}
|
}
|
||||||
|
|
||||||
public func dispose() {
|
public func dispose() {
|
||||||
webView.dispose()
|
onExit()
|
||||||
|
channel?.setMethodCallHandler(nil)
|
||||||
|
channel = nil
|
||||||
|
webView?.dispose()
|
||||||
webView = nil
|
webView = nil
|
||||||
view = nil
|
view = nil
|
||||||
if previousStatusBarStyle != -1 {
|
if previousStatusBarStyle != -1 {
|
||||||
|
@ -563,18 +567,15 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega
|
||||||
backButton.target = nil
|
backButton.target = nil
|
||||||
reloadButton.target = nil
|
reloadButton.target = nil
|
||||||
shareButton.target = nil
|
shareButton.target = nil
|
||||||
onExit()
|
|
||||||
channel?.setMethodCallHandler(nil)
|
|
||||||
channel = nil
|
|
||||||
methodCallDelegate?.webView = nil
|
methodCallDelegate?.webView = nil
|
||||||
methodCallDelegate = nil
|
methodCallDelegate = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
public func onBrowserCreated() {
|
public func onBrowserCreated() {
|
||||||
channel!.invokeMethod("onBrowserCreated", arguments: [])
|
channel?.invokeMethod("onBrowserCreated", arguments: [])
|
||||||
}
|
}
|
||||||
|
|
||||||
public func onExit() {
|
public func onExit() {
|
||||||
channel!.invokeMethod("onExit", arguments: [])
|
channel?.invokeMethod("onExit", arguments: [])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,7 +164,8 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView {
|
||||||
|
|
||||||
func dispose() {
|
func dispose() {
|
||||||
channel?.setMethodCallHandler(nil)
|
channel?.setMethodCallHandler(nil)
|
||||||
methodCallDelegate?.webView = nil
|
channel = nil
|
||||||
|
methodCallDelegate?.dispose()
|
||||||
methodCallDelegate = nil
|
methodCallDelegate = nil
|
||||||
webView?.dispose()
|
webView?.dispose()
|
||||||
webView = nil
|
webView = nil
|
||||||
|
|
|
@ -1791,8 +1791,8 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi
|
||||||
completionHandler(.useCredential, credential)
|
completionHandler(.useCredential, credential)
|
||||||
break
|
break
|
||||||
case 2:
|
case 2:
|
||||||
if InAppWebView.credentialsProposed.count == 0 {
|
if InAppWebView.credentialsProposed.count == 0, let credentialStore = CredentialDatabase.credentialStore {
|
||||||
for (protectionSpace, credentials) in CredentialDatabase.credentialStore!.allCredentials {
|
for (protectionSpace, credentials) in credentialStore.allCredentials {
|
||||||
if protectionSpace.host == host && protectionSpace.realm == realm &&
|
if protectionSpace.host == host && protectionSpace.realm == realm &&
|
||||||
protectionSpace.protocol == prot && protectionSpace.port == port {
|
protectionSpace.protocol == prot && protectionSpace.port == port {
|
||||||
for credential in credentials {
|
for credential in credentials {
|
||||||
|
@ -3023,6 +3023,12 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func dispose() {
|
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()
|
resumeTimers()
|
||||||
stopLoading()
|
stopLoading()
|
||||||
disposeWebMessageChannels()
|
disposeWebMessageChannels()
|
||||||
|
@ -3043,15 +3049,10 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
|
||||||
InAppWebView.windowWebViews.removeValue(forKey: wId)
|
InAppWebView.windowWebViews.removeValue(forKey: wId)
|
||||||
}
|
}
|
||||||
configuration.userContentController.dispose(windowId: windowId)
|
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)
|
NotificationCenter.default.removeObserver(self)
|
||||||
for imp in customIMPs {
|
for imp in customIMPs {
|
||||||
imp_removeBlock(imp)
|
imp_removeBlock(imp)
|
||||||
}
|
}
|
||||||
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.contentOffset))
|
|
||||||
scrollView.removeObserver(self, forKeyPath: #keyPath(UIScrollView.zoomScale))
|
|
||||||
longPressRecognizer.removeTarget(self, action: #selector(longPressGestureDetected))
|
longPressRecognizer.removeTarget(self, action: #selector(longPressGestureDetected))
|
||||||
longPressRecognizer.delegate = nil
|
longPressRecognizer.delegate = nil
|
||||||
scrollView.removeGestureRecognizer(longPressRecognizer)
|
scrollView.removeGestureRecognizer(longPressRecognizer)
|
||||||
|
@ -3068,7 +3069,6 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
|
||||||
navigationDelegate = nil
|
navigationDelegate = nil
|
||||||
scrollView.delegate = nil
|
scrollView.delegate = nil
|
||||||
isPausedTimersCompletionHandler = nil
|
isPausedTimersCompletionHandler = nil
|
||||||
channel = nil
|
|
||||||
SharedLastTouchPointTimestamp.removeValue(forKey: self)
|
SharedLastTouchPointTimestamp.removeValue(forKey: self)
|
||||||
callAsyncJavaScriptBelowIOS14Results.removeAll()
|
callAsyncJavaScriptBelowIOS14Results.removeAll()
|
||||||
super.removeFromSuperview()
|
super.removeFromSuperview()
|
||||||
|
|
|
@ -598,8 +598,12 @@ public class InAppWebViewMethodHandler: FlutterMethodCallDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
public func dispose() {
|
||||||
print("InAppWebViewMethodHandler - dealloc")
|
|
||||||
webView = nil
|
webView = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
print("InAppWebViewMethodHandler - dealloc")
|
||||||
|
dispose()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,4 +72,12 @@ class InAppWebViewStatic: NSObject, FlutterPlugin {
|
||||||
completionHandler(defaultUserAgent)
|
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?,
|
isHttpOnly: Bool?,
|
||||||
sameSite: String?,
|
sameSite: String?,
|
||||||
result: @escaping FlutterResult) {
|
result: @escaping FlutterResult) {
|
||||||
|
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
|
||||||
|
result(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var properties: [HTTPCookiePropertyKey: Any] = [:]
|
var properties: [HTTPCookiePropertyKey: Any] = [:]
|
||||||
properties[.originURL] = url
|
properties[.originURL] = url
|
||||||
properties[.name] = name
|
properties[.name] = name
|
||||||
|
@ -138,7 +143,7 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
||||||
|
|
||||||
let cookie = HTTPCookie(properties: properties)!
|
let cookie = HTTPCookie(properties: properties)!
|
||||||
|
|
||||||
MyCookieManager.httpCookieStore!.setCookie(cookie, completionHandler: {() in
|
httpCookieStore.setCookie(cookie, completionHandler: {() in
|
||||||
result(true)
|
result(true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -146,8 +151,13 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
||||||
public static func getCookies(url: String, result: @escaping FlutterResult) {
|
public static func getCookies(url: String, result: @escaping FlutterResult) {
|
||||||
var cookieList: [[String: Any?]] = []
|
var cookieList: [[String: Any?]] = []
|
||||||
|
|
||||||
|
guard let httpCookieStore = MyCookieManager.httpCookieStore else {
|
||||||
|
result(cookieList)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if let urlHost = URL(string: url)?.host {
|
if let urlHost = URL(string: url)?.host {
|
||||||
MyCookieManager.httpCookieStore!.getAllCookies { (cookies) in
|
httpCookieStore.getAllCookies { (cookies) in
|
||||||
for cookie in cookies {
|
for cookie in cookies {
|
||||||
if urlHost.hasSuffix(cookie.domain) || ".\(urlHost)".hasSuffix(cookie.domain) {
|
if urlHost.hasSuffix(cookie.domain) || ".\(urlHost)".hasSuffix(cookie.domain) {
|
||||||
var sameSite: String? = nil
|
var sameSite: String? = nil
|
||||||
|
@ -189,7 +199,12 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
||||||
public static func getAllCookies(result: @escaping FlutterResult) {
|
public static func getAllCookies(result: @escaping FlutterResult) {
|
||||||
var cookieList: [[String: Any?]] = []
|
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 {
|
for cookie in cookies {
|
||||||
var sameSite: String? = nil
|
var sameSite: String? = nil
|
||||||
if #available(iOS 13.0, *) {
|
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) {
|
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 {
|
for cookie in cookies {
|
||||||
var originURL = ""
|
var originURL = ""
|
||||||
if cookie.properties![.originURL] is String {
|
if cookie.properties![.originURL] is String {
|
||||||
|
@ -234,7 +254,7 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (cookie.domain == domain || cookie.domain == ".\(domain)" || ".\(cookie.domain)" == domain) && cookie.name == name && cookie.path == path {
|
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)
|
result(true)
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
@ -245,7 +265,12 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func deleteCookies(url: String, domain: String, path: String, result: @escaping FlutterResult) {
|
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 {
|
for cookie in cookies {
|
||||||
var originURL = ""
|
var originURL = ""
|
||||||
if cookie.properties![.originURL] is String {
|
if cookie.properties![.originURL] is String {
|
||||||
|
@ -258,7 +283,7 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (cookie.domain == domain || cookie.domain == ".\(domain)" || ".\(cookie.domain)" == domain) && cookie.path == path {
|
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)
|
result(true)
|
||||||
|
@ -272,4 +297,11 @@ class MyCookieManager: NSObject, FlutterPlugin {
|
||||||
result(true)
|
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) {
|
public static func fetchDataRecords(dataTypes: Set<String>, result: @escaping FlutterResult) {
|
||||||
var recordList: [[String: Any?]] = []
|
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 {
|
for record in data {
|
||||||
recordList.append([
|
recordList.append([
|
||||||
"displayName": record.displayName,
|
"displayName": record.displayName,
|
||||||
|
@ -68,7 +74,13 @@ class MyWebStorageManager: NSObject, FlutterPlugin {
|
||||||
|
|
||||||
public static func removeDataFor(dataTypes: Set<String>, recordList: [[String: Any?]], result: @escaping FlutterResult) {
|
public static func removeDataFor(dataTypes: Set<String>, recordList: [[String: Any?]], result: @escaping FlutterResult) {
|
||||||
var records: [WKWebsiteDataRecord] = []
|
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 record in data {
|
||||||
for r in recordList {
|
for r in recordList {
|
||||||
let displayName = r["displayName"] as! String
|
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)
|
result(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func removeDataModifiedSince(dataTypes: Set<String>, timestamp: Int64, result: @escaping FlutterResult) {
|
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))
|
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)
|
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
|
formatter.timeZone = timezone
|
||||||
return formatter.string(from: PlatformUtil.getDateFromMilliseconds(date: date))
|
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 {
|
deinit {
|
||||||
print("PullToRefreshControl - dealloc")
|
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))
|
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 {
|
deinit {
|
||||||
print("SafariViewController - dealloc")
|
print("SafariViewController - dealloc")
|
||||||
|
dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func prepareMethodChannel() {
|
public func prepareMethodChannel() {
|
||||||
|
@ -123,20 +124,21 @@ public class SafariViewController: SFSafariViewController, FlutterPlugin, SFSafa
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public func onChromeSafariBrowserOpened() {
|
public func onChromeSafariBrowserOpened() {
|
||||||
channel!.invokeMethod("onChromeSafariBrowserOpened", arguments: [])
|
channel?.invokeMethod("onChromeSafariBrowserOpened", arguments: [])
|
||||||
}
|
}
|
||||||
|
|
||||||
public func onChromeSafariBrowserCompletedInitialLoad() {
|
public func onChromeSafariBrowserCompletedInitialLoad() {
|
||||||
channel!.invokeMethod("onChromeSafariBrowserCompletedInitialLoad", arguments: [])
|
channel?.invokeMethod("onChromeSafariBrowserCompletedInitialLoad", arguments: [])
|
||||||
}
|
}
|
||||||
|
|
||||||
public func onChromeSafariBrowserClosed() {
|
public func onChromeSafariBrowserClosed() {
|
||||||
channel!.invokeMethod("onChromeSafariBrowserClosed", arguments: [])
|
channel?.invokeMethod("onChromeSafariBrowserClosed", arguments: [])
|
||||||
}
|
}
|
||||||
|
|
||||||
public func dispose() {
|
public func dispose() {
|
||||||
|
channel?.setMethodCallHandler(nil)
|
||||||
|
channel = nil
|
||||||
delegate = nil
|
delegate = nil
|
||||||
channel!.setMethodCallHandler(nil)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +182,12 @@ class CustomUIActivity : UIActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func perform() {
|
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?] = [
|
let arguments: [String: Any?] = [
|
||||||
"url": url.absoluteString,
|
"url": url.absoluteString,
|
||||||
|
|
|
@ -49,16 +49,39 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
|
||||||
headlessInAppWebViewManager = HeadlessInAppWebViewManager(registrar: registrar)
|
headlessInAppWebViewManager = HeadlessInAppWebViewManager(registrar: registrar)
|
||||||
chromeSafariBrowserManager = ChromeSafariBrowserManager(registrar: registrar)
|
chromeSafariBrowserManager = ChromeSafariBrowserManager(registrar: registrar)
|
||||||
inAppWebViewStatic = InAppWebViewStatic(registrar: registrar)
|
inAppWebViewStatic = InAppWebViewStatic(registrar: registrar)
|
||||||
|
credentialDatabase = CredentialDatabase(registrar: registrar)
|
||||||
if #available(iOS 11.0, *) {
|
if #available(iOS 11.0, *) {
|
||||||
myCookieManager = MyCookieManager(registrar: registrar)
|
myCookieManager = MyCookieManager(registrar: registrar)
|
||||||
}
|
}
|
||||||
if #available(iOS 9.0, *) {
|
if #available(iOS 9.0, *) {
|
||||||
myWebStorageManager = MyWebStorageManager(registrar: registrar)
|
myWebStorageManager = MyWebStorageManager(registrar: registrar)
|
||||||
}
|
}
|
||||||
credentialDatabase = CredentialDatabase(registrar: registrar)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||||
SwiftFlutterPlugin.instance = SwiftFlutterPlugin(with: registrar)
|
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> {
|
var contentWorlds: Set<WKContentWorld> {
|
||||||
get {
|
get {
|
||||||
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
||||||
return WKUserContentController._contentWorlds[tmpAddress]!
|
return WKUserContentController._contentWorlds[tmpAddress] ?? []
|
||||||
}
|
}
|
||||||
set(newValue) {
|
set(newValue) {
|
||||||
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
||||||
|
@ -33,7 +33,7 @@ extension WKUserContentController {
|
||||||
var userOnlyScripts: [WKUserScriptInjectionTime:OrderedSet<UserScript>] {
|
var userOnlyScripts: [WKUserScriptInjectionTime:OrderedSet<UserScript>] {
|
||||||
get {
|
get {
|
||||||
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
||||||
return WKUserContentController._userOnlyScripts[tmpAddress]!
|
return WKUserContentController._userOnlyScripts[tmpAddress] ?? [:]
|
||||||
}
|
}
|
||||||
set(newValue) {
|
set(newValue) {
|
||||||
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
||||||
|
@ -45,7 +45,7 @@ extension WKUserContentController {
|
||||||
var pluginScripts: [WKUserScriptInjectionTime:OrderedSet<PluginScript>] {
|
var pluginScripts: [WKUserScriptInjectionTime:OrderedSet<PluginScript>] {
|
||||||
get {
|
get {
|
||||||
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
||||||
return WKUserContentController._pluginScripts[tmpAddress]!
|
return WKUserContentController._pluginScripts[tmpAddress] ?? [:]
|
||||||
}
|
}
|
||||||
set(newValue) {
|
set(newValue) {
|
||||||
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
let tmpAddress = String(format: "%p", unsafeBitCast(self, to: Int.self))
|
||||||
|
|
|
@ -23,5 +23,6 @@ public class WebMessage : NSObject {
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
print("WebMessage - dealloc")
|
print("WebMessage - dealloc")
|
||||||
|
dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,7 @@ public class WebMessageChannel : FlutterMethodCallDelegate {
|
||||||
|
|
||||||
public func dispose() {
|
public func dispose() {
|
||||||
channel?.setMethodCallHandler(nil)
|
channel?.setMethodCallHandler(nil)
|
||||||
|
channel = nil
|
||||||
for port in ports {
|
for port in ports {
|
||||||
port.dispose()
|
port.dispose()
|
||||||
}
|
}
|
||||||
|
@ -140,11 +141,11 @@ public class WebMessageChannel : FlutterMethodCallDelegate {
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
""")
|
""")
|
||||||
channel = nil
|
|
||||||
webView = nil
|
webView = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
print("WebMessageChannel - dealloc")
|
print("WebMessageChannel - dealloc")
|
||||||
|
dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,5 +222,6 @@ public class WebMessageListener : FlutterMethodCallDelegate {
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
print("WebMessageListener - dealloc")
|
print("WebMessageListener - dealloc")
|
||||||
|
dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,5 +118,6 @@ public class WebMessagePort : NSObject {
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
print("WebMessagePort - dealloc")
|
print("WebMessagePort - dealloc")
|
||||||
|
dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ var SharedLastTouchPointTimestamp: [InAppWebView: Int64] = [:]
|
||||||
|
|
||||||
public class Util {
|
public class Util {
|
||||||
public static func getUrlAsset(assetFilePath: String) throws -> URL {
|
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 {
|
guard let assetURL = Bundle.main.url(forResource: key, withExtension: nil) else {
|
||||||
throw NSError(domain: assetFilePath + " asset file cannot be found!", code: 0)
|
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 {
|
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 {
|
guard let assetAbsPath = Bundle.main.path(forResource: key, ofType: nil) else {
|
||||||
throw NSError(domain: assetFilePath + " asset file cannot be found!", code: 0)
|
throw NSError(domain: assetFilePath + " asset file cannot be found!", code: 0)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue