Resolve issue where we could have a web view deallocated before getting displayed.
This commit is contained in:
parent
acaeb4164a
commit
cf8dbb26f7
@ -13,7 +13,7 @@ import RSWeb
|
|||||||
class PreloadedWebView: WKWebView {
|
class PreloadedWebView: WKWebView {
|
||||||
|
|
||||||
private var isReady: Bool = false
|
private var isReady: Bool = false
|
||||||
private var readyCompletion: ((PreloadedWebView) -> Void)?
|
private var readyCompletion: (() -> Void)?
|
||||||
|
|
||||||
init(articleIconSchemeHandler: ArticleIconSchemeHandler) {
|
init(articleIconSchemeHandler: ArticleIconSchemeHandler) {
|
||||||
let preferences = WKPreferences()
|
let preferences = WKPreferences()
|
||||||
@ -44,7 +44,7 @@ class PreloadedWebView: WKWebView {
|
|||||||
loadFileURL(ArticleRenderer.blank.url, allowingReadAccessTo: ArticleRenderer.blank.baseURL)
|
loadFileURL(ArticleRenderer.blank.url, allowingReadAccessTo: ArticleRenderer.blank.baseURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ready(completion: @escaping (PreloadedWebView) -> Void) {
|
func ready(completion: @escaping () -> Void) {
|
||||||
if isReady {
|
if isReady {
|
||||||
completeRequest(completion: completion)
|
completeRequest(completion: completion)
|
||||||
} else {
|
} else {
|
||||||
@ -89,10 +89,10 @@ extension PreloadedWebView: WKNavigationDelegate {
|
|||||||
|
|
||||||
private extension PreloadedWebView {
|
private extension PreloadedWebView {
|
||||||
|
|
||||||
func completeRequest(completion: @escaping (PreloadedWebView) -> Void) {
|
func completeRequest(completion: @escaping () -> Void) {
|
||||||
isReady = false
|
isReady = false
|
||||||
navigationDelegate = nil
|
navigationDelegate = nil
|
||||||
completion(self)
|
completion()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -86,9 +86,7 @@ class WebViewProviderDequeueOperation: MainThreadOperation {
|
|||||||
|
|
||||||
func run() {
|
func run() {
|
||||||
if let webView = queue.lastObject as? PreloadedWebView {
|
if let webView = queue.lastObject as? PreloadedWebView {
|
||||||
webView.ready { preloadedWebView in
|
self.completion(webView)
|
||||||
self.completion(preloadedWebView)
|
|
||||||
}
|
|
||||||
self.queue.remove(webView)
|
self.queue.remove(webView)
|
||||||
self.operationDelegate?.operationDidComplete(self)
|
self.operationDelegate?.operationDidComplete(self)
|
||||||
return
|
return
|
||||||
@ -98,9 +96,7 @@ class WebViewProviderDequeueOperation: MainThreadOperation {
|
|||||||
|
|
||||||
let webView = PreloadedWebView(articleIconSchemeHandler: articleIconSchemeHandler)
|
let webView = PreloadedWebView(articleIconSchemeHandler: articleIconSchemeHandler)
|
||||||
webView.preload()
|
webView.preload()
|
||||||
webView.ready { preloadedWebView in
|
self.completion(webView)
|
||||||
self.completion(preloadedWebView)
|
|
||||||
}
|
|
||||||
self.operationDelegate?.operationDidComplete(self)
|
self.operationDelegate?.operationDidComplete(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,37 +452,41 @@ private extension WebViewController {
|
|||||||
|
|
||||||
sceneModel?.webViewProvider?.dequeueWebView() { webView in
|
sceneModel?.webViewProvider?.dequeueWebView() { webView in
|
||||||
|
|
||||||
// Add the webview
|
webView.ready {
|
||||||
webView.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
self.view.insertSubview(webView, at: 0)
|
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
self.view.leadingAnchor.constraint(equalTo: webView.leadingAnchor),
|
|
||||||
self.view.trailingAnchor.constraint(equalTo: webView.trailingAnchor),
|
|
||||||
self.view.topAnchor.constraint(equalTo: webView.topAnchor),
|
|
||||||
self.view.bottomAnchor.constraint(equalTo: webView.bottomAnchor)
|
|
||||||
])
|
|
||||||
|
|
||||||
// UISplitViewController reports the wrong size to WKWebView which can cause horizontal
|
// Add the webview
|
||||||
// rubberbanding on the iPad. This interferes with our UIPageViewController preventing
|
webView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
// us from easily swiping between WKWebViews. This hack fixes that.
|
self.view.insertSubview(webView, at: 0)
|
||||||
webView.scrollView.contentInset = UIEdgeInsets(top: 0, left: -1, bottom: 0, right: 0)
|
NSLayoutConstraint.activate([
|
||||||
|
self.view.leadingAnchor.constraint(equalTo: webView.leadingAnchor),
|
||||||
|
self.view.trailingAnchor.constraint(equalTo: webView.trailingAnchor),
|
||||||
|
self.view.topAnchor.constraint(equalTo: webView.topAnchor),
|
||||||
|
self.view.bottomAnchor.constraint(equalTo: webView.bottomAnchor)
|
||||||
|
])
|
||||||
|
|
||||||
webView.scrollView.setZoomScale(1.0, animated: false)
|
// UISplitViewController reports the wrong size to WKWebView which can cause horizontal
|
||||||
|
// rubberbanding on the iPad. This interferes with our UIPageViewController preventing
|
||||||
|
// us from easily swiping between WKWebViews. This hack fixes that.
|
||||||
|
webView.scrollView.contentInset = UIEdgeInsets(top: 0, left: -1, bottom: 0, right: 0)
|
||||||
|
|
||||||
self.view.setNeedsLayout()
|
webView.scrollView.setZoomScale(1.0, animated: false)
|
||||||
self.view.layoutIfNeeded()
|
|
||||||
|
|
||||||
// Configure the webview
|
self.view.setNeedsLayout()
|
||||||
webView.navigationDelegate = self
|
self.view.layoutIfNeeded()
|
||||||
webView.uiDelegate = self
|
|
||||||
webView.scrollView.delegate = self
|
|
||||||
// self.configureContextMenuInteraction()
|
|
||||||
|
|
||||||
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasClicked)
|
// Configure the webview
|
||||||
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasShown)
|
webView.navigationDelegate = self
|
||||||
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.showFeedInspector)
|
webView.uiDelegate = self
|
||||||
|
webView.scrollView.delegate = self
|
||||||
|
// self.configureContextMenuInteraction()
|
||||||
|
|
||||||
self.renderPage(webView)
|
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasClicked)
|
||||||
|
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasShown)
|
||||||
|
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.showFeedInspector)
|
||||||
|
|
||||||
|
self.renderPage(webView)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,28 +246,31 @@ private extension WebViewController {
|
|||||||
|
|
||||||
sceneModel?.webViewProvider?.dequeueWebView() { webView in
|
sceneModel?.webViewProvider?.dequeueWebView() { webView in
|
||||||
|
|
||||||
// Add the webview
|
webView.ready {
|
||||||
self.webView = webView
|
|
||||||
|
|
||||||
webView.translatesAutoresizingMaskIntoConstraints = false
|
// Add the webview
|
||||||
self.view.addSubview(webView, positioned: .below, relativeTo: self.statusBarView)
|
self.webView = webView
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
self.view.leadingAnchor.constraint(equalTo: webView.leadingAnchor),
|
|
||||||
self.view.trailingAnchor.constraint(equalTo: webView.trailingAnchor),
|
|
||||||
self.view.topAnchor.constraint(equalTo: webView.topAnchor),
|
|
||||||
self.view.bottomAnchor.constraint(equalTo: webView.bottomAnchor)
|
|
||||||
])
|
|
||||||
|
|
||||||
webView.navigationDelegate = self
|
webView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
self.view.addSubview(webView, positioned: .below, relativeTo: self.statusBarView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
self.view.leadingAnchor.constraint(equalTo: webView.leadingAnchor),
|
||||||
|
self.view.trailingAnchor.constraint(equalTo: webView.trailingAnchor),
|
||||||
|
self.view.topAnchor.constraint(equalTo: webView.topAnchor),
|
||||||
|
self.view.bottomAnchor.constraint(equalTo: webView.bottomAnchor)
|
||||||
|
])
|
||||||
|
|
||||||
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasClicked)
|
webView.navigationDelegate = self
|
||||||
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasShown)
|
|
||||||
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.mouseDidEnter)
|
|
||||||
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.mouseDidExit)
|
|
||||||
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.showFeedInspector)
|
|
||||||
|
|
||||||
self.renderPage(webView)
|
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasClicked)
|
||||||
|
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasShown)
|
||||||
|
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.mouseDidEnter)
|
||||||
|
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.mouseDidExit)
|
||||||
|
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.showFeedInspector)
|
||||||
|
|
||||||
|
self.renderPage(webView)
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import WebKit
|
|||||||
class PreloadedWebView: WKWebView {
|
class PreloadedWebView: WKWebView {
|
||||||
|
|
||||||
private var isReady: Bool = false
|
private var isReady: Bool = false
|
||||||
private var readyCompletion: ((PreloadedWebView) -> Void)?
|
private var readyCompletion: (() -> Void)?
|
||||||
|
|
||||||
init(articleIconSchemeHandler: ArticleIconSchemeHandler) {
|
init(articleIconSchemeHandler: ArticleIconSchemeHandler) {
|
||||||
let preferences = WKPreferences()
|
let preferences = WKPreferences()
|
||||||
@ -38,7 +38,7 @@ class PreloadedWebView: WKWebView {
|
|||||||
loadFileURL(ArticleRenderer.blank.url, allowingReadAccessTo: ArticleRenderer.blank.baseURL)
|
loadFileURL(ArticleRenderer.blank.url, allowingReadAccessTo: ArticleRenderer.blank.baseURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ready(completion: @escaping (PreloadedWebView) -> Void) {
|
func ready(completion: @escaping () -> Void) {
|
||||||
if isReady {
|
if isReady {
|
||||||
completeRequest(completion: completion)
|
completeRequest(completion: completion)
|
||||||
} else {
|
} else {
|
||||||
@ -66,10 +66,10 @@ extension PreloadedWebView: WKNavigationDelegate {
|
|||||||
|
|
||||||
private extension PreloadedWebView {
|
private extension PreloadedWebView {
|
||||||
|
|
||||||
func completeRequest(completion: @escaping (PreloadedWebView) -> Void) {
|
func completeRequest(completion: @escaping () -> Void) {
|
||||||
isReady = false
|
isReady = false
|
||||||
navigationDelegate = nil
|
navigationDelegate = nil
|
||||||
completion(self)
|
completion()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -483,37 +483,41 @@ private extension WebViewController {
|
|||||||
|
|
||||||
coordinator.webViewProvider.dequeueWebView() { webView in
|
coordinator.webViewProvider.dequeueWebView() { webView in
|
||||||
|
|
||||||
// Add the webview
|
webView.ready {
|
||||||
webView.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
self.view.insertSubview(webView, at: 0)
|
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
self.view.leadingAnchor.constraint(equalTo: webView.leadingAnchor),
|
|
||||||
self.view.trailingAnchor.constraint(equalTo: webView.trailingAnchor),
|
|
||||||
self.view.topAnchor.constraint(equalTo: webView.topAnchor),
|
|
||||||
self.view.bottomAnchor.constraint(equalTo: webView.bottomAnchor)
|
|
||||||
])
|
|
||||||
|
|
||||||
// UISplitViewController reports the wrong size to WKWebView which can cause horizontal
|
// Add the webview
|
||||||
// rubberbanding on the iPad. This interferes with our UIPageViewController preventing
|
webView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
// us from easily swiping between WKWebViews. This hack fixes that.
|
self.view.insertSubview(webView, at: 0)
|
||||||
webView.scrollView.contentInset = UIEdgeInsets(top: 0, left: -1, bottom: 0, right: 0)
|
NSLayoutConstraint.activate([
|
||||||
|
self.view.leadingAnchor.constraint(equalTo: webView.leadingAnchor),
|
||||||
|
self.view.trailingAnchor.constraint(equalTo: webView.trailingAnchor),
|
||||||
|
self.view.topAnchor.constraint(equalTo: webView.topAnchor),
|
||||||
|
self.view.bottomAnchor.constraint(equalTo: webView.bottomAnchor)
|
||||||
|
])
|
||||||
|
|
||||||
webView.scrollView.setZoomScale(1.0, animated: false)
|
// UISplitViewController reports the wrong size to WKWebView which can cause horizontal
|
||||||
|
// rubberbanding on the iPad. This interferes with our UIPageViewController preventing
|
||||||
|
// us from easily swiping between WKWebViews. This hack fixes that.
|
||||||
|
webView.scrollView.contentInset = UIEdgeInsets(top: 0, left: -1, bottom: 0, right: 0)
|
||||||
|
|
||||||
self.view.setNeedsLayout()
|
webView.scrollView.setZoomScale(1.0, animated: false)
|
||||||
self.view.layoutIfNeeded()
|
|
||||||
|
|
||||||
// Configure the webview
|
self.view.setNeedsLayout()
|
||||||
webView.navigationDelegate = self
|
self.view.layoutIfNeeded()
|
||||||
webView.uiDelegate = self
|
|
||||||
webView.scrollView.delegate = self
|
|
||||||
self.configureContextMenuInteraction()
|
|
||||||
|
|
||||||
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasClicked)
|
// Configure the webview
|
||||||
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasShown)
|
webView.navigationDelegate = self
|
||||||
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.showFeedInspector)
|
webView.uiDelegate = self
|
||||||
|
webView.scrollView.delegate = self
|
||||||
|
self.configureContextMenuInteraction()
|
||||||
|
|
||||||
self.renderPage(webView)
|
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasClicked)
|
||||||
|
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.imageWasShown)
|
||||||
|
webView.configuration.userContentController.add(WrapperScriptMessageHandler(self), name: MessageName.showFeedInspector)
|
||||||
|
|
||||||
|
self.renderPage(webView)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,9 +86,7 @@ class WebViewProviderDequeueOperation: MainThreadOperation {
|
|||||||
|
|
||||||
func run() {
|
func run() {
|
||||||
if let webView = queue.lastObject as? PreloadedWebView {
|
if let webView = queue.lastObject as? PreloadedWebView {
|
||||||
webView.ready { preloadedWebView in
|
self.completion(webView)
|
||||||
self.completion(preloadedWebView)
|
|
||||||
}
|
|
||||||
self.queue.remove(webView)
|
self.queue.remove(webView)
|
||||||
self.operationDelegate?.operationDidComplete(self)
|
self.operationDelegate?.operationDidComplete(self)
|
||||||
return
|
return
|
||||||
@ -98,9 +96,7 @@ class WebViewProviderDequeueOperation: MainThreadOperation {
|
|||||||
|
|
||||||
let webView = PreloadedWebView(articleIconSchemeHandler: articleIconSchemeHandler)
|
let webView = PreloadedWebView(articleIconSchemeHandler: articleIconSchemeHandler)
|
||||||
webView.preload()
|
webView.preload()
|
||||||
webView.ready { preloadedWebView in
|
self.completion(webView)
|
||||||
self.completion(preloadedWebView)
|
|
||||||
}
|
|
||||||
self.operationDelegate?.operationDidComplete(self)
|
self.operationDelegate?.operationDidComplete(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user