Skip to content

Commit

Permalink
Try to avoid crash by apply Telerik-Verified-Plugins/WKWebView#248 (c…
Browse files Browse the repository at this point in the history
  • Loading branch information
ainopara committed Jan 7, 2017
1 parent b6a55f0 commit 8d622a9
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 44 deletions.
25 changes: 7 additions & 18 deletions Stage1st/ContentViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,6 @@ class S1ContentViewController: UIViewController, ImagePresenter, UserPresenter,
NotificationCenter.default.removeObserver(self)
webView.configuration.userContentController.removeScriptMessageHandler(forName: "stage1st")
pullToActionController.stop()
webView.navigationDelegate = nil
webView.stopLoading()
DDLogInfo("[ContentVC] Dealloced")
}
}
Expand Down Expand Up @@ -366,7 +364,6 @@ extension S1ContentViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

let previousPresentType = presentType
presentType = .none

// defer from initializer to here to make sure navigationController exist (i.e. self be added to navigation stack)
Expand All @@ -378,11 +375,7 @@ extension S1ContentViewController {
didReceivePaletteChangeNotification(nil)

// Also use this method to initialize content.
if case .image = previousPresentType {
// Note: Calling evaluateJavaScript to WKWebView will cause the content of it changed to blank before completionHandler return. That will lead to screen blink when user coming back from image viewer.
} else {
_tryToReloadWKWebViewIfPageIsBlankDueToMemoryWarning()
}
_tryToReloadWKWebViewIfPageIsBlankDueToWebKitProcessTerminated()
}

override func viewDidDisappear(_ animated: Bool) {
Expand All @@ -399,7 +392,7 @@ extension S1ContentViewController {

func applicationWillEnterForeground() {
DDLogDebug("[ContentVC] \(self) will enter foreground begin")
_tryToReloadWKWebViewIfPageIsBlankDueToMemoryWarning()
_tryToReloadWKWebViewIfPageIsBlankDueToWebKitProcessTerminated()
}

func applicationDidEnterBackground() {
Expand Down Expand Up @@ -761,7 +754,7 @@ extension S1ContentViewController: WKNavigationDelegate {
}

func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
DDLogInfo("[ContentVC] webViewWebContentProcessDidTerminate")
DDLogError("[ContentVC] webViewWebContentProcessDidTerminate")
}

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
Expand Down Expand Up @@ -1287,14 +1280,10 @@ extension S1ContentViewController {
bottomDecorateLine.isHidden = !self.finishFirstLoading.value
}

func _tryToReloadWKWebViewIfPageIsBlankDueToMemoryWarning() {
// http://stackoverflow.com/questions/27809259/detecting-whether-a-wkwebview-has-blanked
webView.evaluateJavaScript("document.querySelector('body').innerHTML") { [weak self] (result, error) in
guard let strongSelf = self else { return }
guard let result = result as? String, result != "" else {
strongSelf.refreshCurrentPage(forceUpdate: !strongSelf.finishFirstLoading.value && strongSelf.viewModel.isInLastPage(), scrollType: .restorePosition)
return
}
func _tryToReloadWKWebViewIfPageIsBlankDueToWebKitProcessTerminated() {
guard let title = webView.title, title != "" else {
refreshCurrentPage(forceUpdate: !finishFirstLoading.value && viewModel.isInLastPage(), scrollType: .restorePosition)
return
}
}

Expand Down
37 changes: 22 additions & 15 deletions Stage1st/S1QuoteFloorViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class S1QuoteFloorViewController: UIViewController, ImagePresenter, UserPresente
webView.scrollView.delegate = self
webView.isOpaque = false

NotificationCenter.default.addObserver(self,
selector: #selector(applicationWillEnterForeground),
name: .UIApplicationWillEnterForeground,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(didReceivePaletteChangeNotification(_:)),
name: .APPaletteDidChangeNotification,
Expand All @@ -61,7 +65,6 @@ class S1QuoteFloorViewController: UIViewController, ImagePresenter, UserPresente
DDLogInfo("[QuoteFloorVC] Dealloc Begin")
NotificationCenter.default.removeObserver(self)
webView.configuration.userContentController.removeScriptMessageHandler(forName: "stage1st")
webView.navigationDelegate = nil
webView.stopLoading()
DDLogInfo("[QuoteFloorVC] Dealloced")
}
Expand All @@ -81,7 +84,6 @@ class S1QuoteFloorViewController: UIViewController, ImagePresenter, UserPresente
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

let previousPresentType = presentType
presentType = .none

// defer from initializer to here to make sure navigationController exist (i.e. self be added to navigation stack)
Expand All @@ -92,19 +94,13 @@ class S1QuoteFloorViewController: UIViewController, ImagePresenter, UserPresente

didReceivePaletteChangeNotification(nil)

// http://stackoverflow.com/questions/27809259/detecting-whether-a-wkwebview-has-blanked
// Also use this method to initialize content.
if case .image = previousPresentType {
/// Note: Calling evaluateJavaScript to WKWebView will cause the content of it changed to blank before completionHandler return. That will lead to screen blink when user coming back from image viewer.
} else {
webView.evaluateJavaScript("document.querySelector('body').innerHTML") { [weak self] (result, error) in
guard let strongSelf = self else { return }
guard let result = result as? String, result != "" else {
strongSelf.webView.loadHTMLString(strongSelf.viewModel.generatePage(with: strongSelf.viewModel.floors), baseURL: strongSelf.viewModel.baseURL)
return
}
}
}
_tryToReloadWKWebViewIfPageIsBlankDueToWebKitProcessTerminated()
}

func applicationWillEnterForeground() {
DDLogDebug("[QuoteFloorVC] \(self) will enter foreground begin")
_tryToReloadWKWebViewIfPageIsBlankDueToWebKitProcessTerminated()
DDLogDebug("[QuoteFloorVC] \(self) will enter foreground end")
}
}

Expand Down Expand Up @@ -241,6 +237,10 @@ extension S1QuoteFloorViewController: WKNavigationDelegate {
return
}

func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
DDLogError("[QuoteFloor] \(#function)")
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
DispatchQueue.global().async { [weak self] in
guard let strongSelf = self else { return }
Expand Down Expand Up @@ -270,6 +270,13 @@ extension S1QuoteFloorViewController {
return 0.0
}
}

func _tryToReloadWKWebViewIfPageIsBlankDueToWebKitProcessTerminated() {
guard let title = webView.title, title != "" else {
webView.loadHTMLString(viewModel.generatePage(with: viewModel.floors), baseURL: viewModel.baseURL)
return
}
}
}

// MARK: - Style
Expand Down
38 changes: 27 additions & 11 deletions Vendors/S1WebViewController/WebViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,14 @@ class WebViewController: UIViewController, WKNavigationDelegate {

updateBarItems()

NotificationCenter.default.addObserver(self, selector: #selector(didReceivePaletteChangeNotification(_:)), name: .APPaletteDidChangeNotification, object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(applicationWillEnterForeground),
name: .UIApplicationWillEnterForeground,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(didReceivePaletteChangeNotification(_:)),
name: .APPaletteDidChangeNotification,
object: nil)
}

required init?(coder aDecoder: NSCoder) {
Expand Down Expand Up @@ -133,16 +140,14 @@ class WebViewController: UIViewController, WKNavigationDelegate {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.didReceivePaletteChangeNotification(nil)
DDLogInfo("[WebVC] view will appear")

// http://stackoverflow.com/questions/27809259/detecting-whether-a-wkwebview-has-blanked
// Also use this method to initialize content.
webView.evaluateJavaScript("document.querySelector('body').innerHTML") { [weak self] (result, error) in
guard let strongSelf = self else { return }
guard let result = result as? String, result != "" else {
strongSelf.webView.load(URLRequest(url: strongSelf.currentValidURL()))
return
}
}
_tryToReloadWKWebViewIfPageIsBlankDueToWebKitProcessTerminated()
}

func applicationWillEnterForeground() {
DDLogDebug("[WebVC] \(self) will enter foreground begin")
_tryToReloadWKWebViewIfPageIsBlankDueToWebKitProcessTerminated()
}

// MARK: Layout
Expand Down Expand Up @@ -184,7 +189,7 @@ class WebViewController: UIViewController, WKNavigationDelegate {
}
}

// MARK: - UIWebViewDelegate
// MARK: - WKWebViewNavigationDelegate
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
DDLogDebug("[WebVC] didCommit")
updateBarItems()
Expand All @@ -206,6 +211,10 @@ class WebViewController: UIViewController, WKNavigationDelegate {
updateBarItems()
}

func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
DDLogError("[WebVC] \(#function)")
}

// MARK: KVO
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard let newProgress = change?[NSKeyValueChangeKey.newKey] as? Float else { return }
Expand Down Expand Up @@ -248,6 +257,13 @@ class WebViewController: UIViewController, WKNavigationDelegate {
}
}

func _tryToReloadWKWebViewIfPageIsBlankDueToWebKitProcessTerminated() {
guard let title = webView.title, title != "" else {
webView.load(URLRequest(url: currentValidURL()))
return
}
}

// MARK: - Notification
override func didReceivePaletteChangeNotification(_ notification: Notification?) {
statusBarSeparatorView.backgroundColor = APColorManager.shared.colorForKey("default.text.tint")
Expand Down

0 comments on commit 8d622a9

Please sign in to comment.