From e62348adc7efae3ce38dc6c84729ed17c0f361c2 Mon Sep 17 00:00:00 2001 From: Lorenzo Pichilli Date: Fri, 10 Nov 2023 19:57:02 +0100 Subject: [PATCH] fix #1500, close #1513 --- CHANGELOG.md | 1 + .../InAppBrowserWebViewController.swift | 4 +- .../FlutterWebViewController.swift | 4 +- ios/Classes/InAppWebView/InAppWebView.swift | 103 ++++++++++++------ .../InAppBrowserWebViewController.swift | 4 +- .../FlutterWebViewController.swift | 4 +- macos/Classes/InAppWebView/InAppWebView.swift | 99 +++++++++++------ 7 files changed, 143 insertions(+), 76 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e064e4a..40b7c49d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Merged "Fix ios multiple flutter presenting error" [#1736](https://github.com/pichillilorenzo/flutter_inappwebview/pull/1736) (thanks to [AlexT84](https://github.com/AlexT84)) - Merged "fix cert parsing for ios 12" [#1822](https://github.com/pichillilorenzo/flutter_inappwebview/pull/1822) (thanks to [darkang3lz92](https://github.com/darkang3lz92)) - Merged "Fix iOS and macOS Forced unwrap null value HTTPCookie for CookieManager.setCookie" [#1677](https://github.com/pichillilorenzo/flutter_inappwebview/pull/1677) (thanks to [maxmitz](https://github.com/maxmitz)) +- Fixed "iOS about:blank popup not loading page" [#1500](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1500) ## 6.0.0-beta.25 diff --git a/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift b/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift index bd475d03..f96f9053 100755 --- a/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift +++ b/ios/Classes/InAppBrowser/InAppBrowserWebViewController.swift @@ -145,9 +145,9 @@ public class InAppBrowserWebViewController: UIViewController, InAppBrowserDelega } } - if let wId = windowId, let webViewTransport = plugin?.inAppWebViewManager?.windowWebViews[wId] { - webView?.load(webViewTransport.request) + if let wId = windowId { channelDelegate?.onBrowserCreated() + webView?.runWindowBeforeCreatedCallbacks() } else { if #available(iOS 11.0, *) { if let contentBlockers = webView?.settings?.contentBlockers, contentBlockers.count > 0 { diff --git a/ios/Classes/InAppWebView/FlutterWebViewController.swift b/ios/Classes/InAppWebView/FlutterWebViewController.swift index 6fef9088..5eda9f19 100755 --- a/ios/Classes/InAppWebView/FlutterWebViewController.swift +++ b/ios/Classes/InAppWebView/FlutterWebViewController.swift @@ -138,8 +138,8 @@ public class FlutterWebViewController: NSObject, FlutterPlatformView, Disposable } load(initialUrlRequest: initialUrlRequest, initialFile: initialFile, initialData: initialData) } - else if let wId = windowId, let webViewTransport = webView.plugin?.inAppWebViewManager?.windowWebViews[wId] { - webView.load(webViewTransport.request) + else if let wId = windowId { + webView.runWindowBeforeCreatedCallbacks() } } diff --git a/ios/Classes/InAppWebView/InAppWebView.swift b/ios/Classes/InAppWebView/InAppWebView.swift index 4bf17c80..9b30b023 100755 --- a/ios/Classes/InAppWebView/InAppWebView.swift +++ b/ios/Classes/InAppWebView/InAppWebView.swift @@ -20,6 +20,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, var plugin: SwiftFlutterPlugin? var windowId: Int64? var windowCreated = false + var windowBeforeCreatedCallbacks: [() -> ()] = [] var inAppBrowserDelegate: InAppBrowserDelegate? var channelDelegate: WebViewChannelDelegate? var settings: InAppWebViewSettings? @@ -1774,12 +1775,6 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { - - if windowId != nil, !windowCreated { - decisionHandler(.cancel) - return - } - var decisionHandlerCalled = false let callback = WebViewChannelDelegate.ShouldOverrideUrlLoadingCallback() callback.nonNullSuccess = { (response: WKNavigationActionPolicy) in @@ -1798,10 +1793,18 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, callback?.defaultBehaviour(nil) } - if let useShouldOverrideUrlLoading = settings?.useShouldOverrideUrlLoading, useShouldOverrideUrlLoading, let channelDelegate = channelDelegate { - channelDelegate.shouldOverrideUrlLoading(navigationAction: navigationAction, callback: callback) + let runCallback = { + if let useShouldOverrideUrlLoading = self.settings?.useShouldOverrideUrlLoading, useShouldOverrideUrlLoading, let channelDelegate = self.channelDelegate { + channelDelegate.shouldOverrideUrlLoading(navigationAction: navigationAction, callback: callback) + } else { + callback.defaultBehaviour(nil) + } + } + + if windowId != nil, !windowCreated { + windowBeforeCreatedCallbacks.append(runCallback) } else { - callback.defaultBehaviour(nil) + runCallback() } } @@ -1946,12 +1949,6 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, } public func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { - - if windowId != nil, !windowCreated { - completionHandler(.cancelAuthenticationChallenge, nil) - return - } - var completionHandlerCalled = false if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic || challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodDefault || @@ -2025,10 +2022,18 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, callback?.defaultBehaviour(nil) } - if let channelDelegate = channelDelegate { - channelDelegate.onReceivedHttpAuthRequest(challenge: HttpAuthenticationChallenge(fromChallenge: challenge), callback: callback) + let runCallback = { + if let channelDelegate = self.channelDelegate { + channelDelegate.onReceivedHttpAuthRequest(challenge: HttpAuthenticationChallenge(fromChallenge: challenge), callback: callback) + } else { + callback.defaultBehaviour(nil) + } + } + + if windowId != nil, !windowCreated { + windowBeforeCreatedCallbacks.append(runCallback) } else { - callback.defaultBehaviour(nil) + runCallback() } } else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { @@ -2076,10 +2081,18 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, callback?.defaultBehaviour(nil) } - if let channelDelegate = channelDelegate { - channelDelegate.onReceivedServerTrustAuthRequest(challenge: ServerTrustChallenge(fromChallenge: challenge), callback: callback) + let runCallback = { + if let channelDelegate = self.channelDelegate { + channelDelegate.onReceivedServerTrustAuthRequest(challenge: ServerTrustChallenge(fromChallenge: challenge), callback: callback) + } else { + callback.defaultBehaviour(nil) + } + } + + if windowId != nil, !windowCreated { + windowBeforeCreatedCallbacks.append(runCallback) } else { - callback.defaultBehaviour(nil) + runCallback() } } else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate { @@ -2135,10 +2148,18 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, callback?.defaultBehaviour(nil) } - if let channelDelegate = channelDelegate { - channelDelegate.onReceivedClientCertRequest(challenge: ClientCertChallenge(fromChallenge: challenge), callback: callback) + let runCallback = { + if let channelDelegate = self.channelDelegate { + channelDelegate.onReceivedClientCertRequest(challenge: ClientCertChallenge(fromChallenge: challenge), callback: callback) + } else { + callback.defaultBehaviour(nil) + } + } + + if windowId != nil, !windowCreated { + windowBeforeCreatedCallbacks.append(runCallback) } else { - callback.defaultBehaviour(nil) + runCallback() } } else { @@ -2471,6 +2492,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { + var windowId: Int64 = 0 let inAppWebViewManager = plugin?.inAppWebViewManager if let inAppWebViewManager = inAppWebViewManager { @@ -2478,16 +2500,15 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, windowId = inAppWebViewManager.windowAutoincrementId } - let windowWebView = InAppWebView(id: nil, plugin: nil, frame: CGRect.zero, configuration: configuration, contextMenu: nil) + let windowWebView = InAppWebView(id: nil, plugin: nil, frame: self.bounds, configuration: configuration, contextMenu: nil) windowWebView.windowId = windowId - + let webViewTransport = WebViewTransport( webView: windowWebView, request: navigationAction.request ) inAppWebViewManager?.windowWebViews[windowId] = webViewTransport - windowWebView.stopLoading() let createWindowAction = CreateWindowAction(navigationAction: navigationAction, windowId: windowId, windowFeatures: windowFeatures, isDialog: nil) @@ -2518,11 +2539,6 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, public func webView(_ webView: WKWebView, authenticationChallenge challenge: URLAuthenticationChallenge, shouldAllowDeprecatedTLS decisionHandler: @escaping (Bool) -> Void) { - if windowId != nil, !windowCreated { - decisionHandler(false) - return - } - var decisionHandlerCalled = false let callback = WebViewChannelDelegate.ShouldAllowDeprecatedTLSCallback() callback.nonNullSuccess = { (action: Bool) in @@ -2541,10 +2557,18 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, callback?.defaultBehaviour(nil) } - if let channelDelegate = channelDelegate { - channelDelegate.shouldAllowDeprecatedTLS(challenge: challenge, callback: callback) + let runCallback = { + if let channelDelegate = self.channelDelegate { + channelDelegate.shouldAllowDeprecatedTLS(challenge: challenge, callback: callback) + } else { + callback.defaultBehaviour(nil) + } + } + + if windowId != nil, !windowCreated { + windowBeforeCreatedCallbacks.append(runCallback) } else { - callback.defaultBehaviour(nil) + runCallback() } } @@ -3194,9 +3218,18 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) { return settings?.disableInputAccessoryView ?? false ? nil : super.inputAccessoryView } + public func runWindowBeforeCreatedCallbacks() { + let callbacks = windowBeforeCreatedCallbacks + callbacks.forEach { (callback) in + callback() + } + windowBeforeCreatedCallbacks.removeAll() + } + public func dispose() { channelDelegate?.dispose() channelDelegate = nil + runWindowBeforeCreatedCallbacks() removeObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress)) removeObserver(self, forKeyPath: #keyPath(WKWebView.url)) removeObserver(self, forKeyPath: #keyPath(WKWebView.title)) diff --git a/macos/Classes/InAppBrowser/InAppBrowserWebViewController.swift b/macos/Classes/InAppBrowser/InAppBrowserWebViewController.swift index 7a287778..5ab6a9af 100755 --- a/macos/Classes/InAppBrowser/InAppBrowserWebViewController.swift +++ b/macos/Classes/InAppBrowser/InAppBrowserWebViewController.swift @@ -100,9 +100,9 @@ public class InAppBrowserWebViewController: NSViewController, InAppBrowserDelega progressBar.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0.0).isActive = true progressBar.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0.0).isActive = true - if let wId = windowId, let webViewTransport = plugin?.inAppWebViewManager?.windowWebViews[wId] { - webView?.load(webViewTransport.request) + if let wId = windowId { channelDelegate?.onBrowserCreated() + webView?.runWindowBeforeCreatedCallbacks() } else { if #available(macOS 10.13, *) { if let contentBlockers = webView?.settings?.contentBlockers, contentBlockers.count > 0 { diff --git a/macos/Classes/InAppWebView/FlutterWebViewController.swift b/macos/Classes/InAppWebView/FlutterWebViewController.swift index fd6d03d9..df77762c 100755 --- a/macos/Classes/InAppWebView/FlutterWebViewController.swift +++ b/macos/Classes/InAppWebView/FlutterWebViewController.swift @@ -127,8 +127,8 @@ public class FlutterWebViewController: NSObject, /*FlutterPlatformView,*/ Dispos } load(initialUrlRequest: initialUrlRequest, initialFile: initialFile, initialData: initialData) } - else if let wId = windowId, let webViewTransport = webView.plugin?.inAppWebViewManager?.windowWebViews[wId] { - webView.load(webViewTransport.request) + else if let wId = windowId { + webView.runWindowBeforeCreatedCallbacks() } } diff --git a/macos/Classes/InAppWebView/InAppWebView.swift b/macos/Classes/InAppWebView/InAppWebView.swift index e5575dd5..5cee0329 100755 --- a/macos/Classes/InAppWebView/InAppWebView.swift +++ b/macos/Classes/InAppWebView/InAppWebView.swift @@ -19,6 +19,7 @@ public class InAppWebView: WKWebView, WKUIDelegate, var plugin: InAppWebViewFlutterPlugin? var windowId: Int64? var windowCreated = false + var windowBeforeCreatedCallbacks: [() -> ()] = [] var inAppBrowserDelegate: InAppBrowserDelegate? var channelDelegate: WebViewChannelDelegate? var settings: InAppWebViewSettings? @@ -1165,12 +1166,6 @@ public class InAppWebView: WKWebView, WKUIDelegate, public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { - - if windowId != nil, !windowCreated { - decisionHandler(.cancel) - return - } - var decisionHandlerCalled = false let callback = WebViewChannelDelegate.ShouldOverrideUrlLoadingCallback() callback.nonNullSuccess = { (response: WKNavigationActionPolicy) in @@ -1188,11 +1183,19 @@ public class InAppWebView: WKWebView, WKUIDelegate, print(code + ", " + (message ?? "")) callback?.defaultBehaviour(nil) } - - if let useShouldOverrideUrlLoading = settings?.useShouldOverrideUrlLoading, useShouldOverrideUrlLoading, let channelDelegate = channelDelegate { - channelDelegate.shouldOverrideUrlLoading(navigationAction: navigationAction, callback: callback) + + let runCallback = { + if let useShouldOverrideUrlLoading = self.settings?.useShouldOverrideUrlLoading, useShouldOverrideUrlLoading, let channelDelegate = self.channelDelegate { + channelDelegate.shouldOverrideUrlLoading(navigationAction: navigationAction, callback: callback) + } else { + callback.defaultBehaviour(nil) + } + } + + if windowId != nil, !windowCreated { + windowBeforeCreatedCallbacks.append(runCallback) } else { - callback.defaultBehaviour(nil) + runCallback() } } @@ -1328,12 +1331,6 @@ public class InAppWebView: WKWebView, WKUIDelegate, } public func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { - - if windowId != nil, !windowCreated { - completionHandler(.cancelAuthenticationChallenge, nil) - return - } - var completionHandlerCalled = false if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodHTTPBasic || challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodDefault || @@ -1407,10 +1404,18 @@ public class InAppWebView: WKWebView, WKUIDelegate, callback?.defaultBehaviour(nil) } - if let channelDelegate = channelDelegate { - channelDelegate.onReceivedHttpAuthRequest(challenge: HttpAuthenticationChallenge(fromChallenge: challenge), callback: callback) + let runCallback = { + if let channelDelegate = self.channelDelegate { + channelDelegate.onReceivedHttpAuthRequest(challenge: HttpAuthenticationChallenge(fromChallenge: challenge), callback: callback) + } else { + callback.defaultBehaviour(nil) + } + } + + if windowId != nil, !windowCreated { + windowBeforeCreatedCallbacks.append(runCallback) } else { - callback.defaultBehaviour(nil) + runCallback() } } else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { @@ -1458,10 +1463,18 @@ public class InAppWebView: WKWebView, WKUIDelegate, callback?.defaultBehaviour(nil) } - if let channelDelegate = channelDelegate { - channelDelegate.onReceivedServerTrustAuthRequest(challenge: ServerTrustChallenge(fromChallenge: challenge), callback: callback) + let runCallback = { + if let channelDelegate = self.channelDelegate { + channelDelegate.onReceivedServerTrustAuthRequest(challenge: ServerTrustChallenge(fromChallenge: challenge), callback: callback) + } else { + callback.defaultBehaviour(nil) + } + } + + if windowId != nil, !windowCreated { + windowBeforeCreatedCallbacks.append(runCallback) } else { - callback.defaultBehaviour(nil) + runCallback() } } else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate { @@ -1515,10 +1528,18 @@ public class InAppWebView: WKWebView, WKUIDelegate, callback?.defaultBehaviour(nil) } - if let channelDelegate = channelDelegate { - channelDelegate.onReceivedClientCertRequest(challenge: ClientCertChallenge(fromChallenge: challenge), callback: callback) + let runCallback = { + if let channelDelegate = self.channelDelegate { + channelDelegate.onReceivedClientCertRequest(challenge: ClientCertChallenge(fromChallenge: challenge), callback: callback) + } else { + callback.defaultBehaviour(nil) + } + } + + if windowId != nil, !windowCreated { + windowBeforeCreatedCallbacks.append(runCallback) } else { - callback.defaultBehaviour(nil) + runCallback() } } else { @@ -1832,11 +1853,6 @@ public class InAppWebView: WKWebView, WKUIDelegate, public func webView(_ webView: WKWebView, authenticationChallenge challenge: URLAuthenticationChallenge, shouldAllowDeprecatedTLS decisionHandler: @escaping (Bool) -> Void) { - if windowId != nil, !windowCreated { - decisionHandler(false) - return - } - var decisionHandlerCalled = false let callback = WebViewChannelDelegate.ShouldAllowDeprecatedTLSCallback() callback.nonNullSuccess = { (action: Bool) in @@ -1855,10 +1871,18 @@ public class InAppWebView: WKWebView, WKUIDelegate, callback?.defaultBehaviour(nil) } - if let channelDelegate = channelDelegate { - channelDelegate.shouldAllowDeprecatedTLS(challenge: challenge, callback: callback) + let runCallback = { + if let channelDelegate = self.channelDelegate { + channelDelegate.shouldAllowDeprecatedTLS(challenge: challenge, callback: callback) + } else { + callback.defaultBehaviour(nil) + } + } + + if windowId != nil, !windowCreated { + windowBeforeCreatedCallbacks.append(runCallback) } else { - callback.defaultBehaviour(nil) + runCallback() } } @@ -2534,9 +2558,18 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) { } } + public func runWindowBeforeCreatedCallbacks() { + let callbacks = windowBeforeCreatedCallbacks + callbacks.forEach { (callback) in + callback() + } + windowBeforeCreatedCallbacks.removeAll() + } + public func dispose() { channelDelegate?.dispose() channelDelegate = nil + runWindowBeforeCreatedCallbacks() currentOpenPanel?.cancel(self) currentOpenPanel?.close() currentOpenPanel = nil