How to clear the WKBackForwardList of a WKWebView?

匿名 (未验证) 提交于 2019-12-03 01:33:01

问题:

It appears that the backForwardList of a WKWebView is readonly, but I've seen people so some pretty magical things to get around this. I need to figure out some way of clearing the history of a WKWebView. Any ideas how I might so this? So far I've tries a few tricks that have failed:

  • using keyValue:forKey didn't work.
  • using a C pointer -> didnt work.

I've seen people talk about synthesizing the property and extending the class but I don't really know how that works and couldn't figure it out. Any other ideas?

回答1:

This code compiles, but I have not tested it...

First I subclass WKWebView to override backForwardList with my own subclass of WKBackForwardList.

Then, in my WKBackForwardList subclass, I can either override backItem & forwardItem to make them return nil, instead of having them look into their respective list (which is most probably the default implementation).

Or I can override backList & forwardList in the same way I did in WKWebView with backForwardList. I do this to add a setter, which will allow me remove items from the lists.

import Foundation import WebKit  class WebViewHistory: WKBackForwardList {      /* Solution 1: return nil, discarding what is in backList & forwardList */      override var backItem: WKBackForwardListItem? {         return nil     }      override var forwardItem: WKBackForwardListItem? {         return nil     }      /* Solution 2: override backList and forwardList to add a setter */      var myBackList = [WKBackForwardListItem]()      override var backList: [WKBackForwardListItem] {         get {             return myBackList         }         set(list) {             myBackList = list         }     }      func clearBackList() {         backList.removeAll()     } }  class WebView: WKWebView {      var history: WebViewHistory      override var backForwardList: WebViewHistory {         return history     }      init(frame: CGRect, configuration: WKWebViewConfiguration, history: WebViewHistory) {         self.history = history         super.init(frame: frame, configuration: configuration)     }      /* Not sure about the best way to handle this part, it was just required for the code to compile... */      required init?(coder: NSCoder) {          if let history = coder.decodeObject(forKey: "history") as? WebViewHistory {             self.history = history         }         else {             history = WebViewHistory()         }          super.init(coder: coder)     }      override func encode(with aCoder: NSCoder) {         super.encode(with: aCoder)         aCoder.encode(history, forKey: "history")     } } 


回答2:

Worded on iOS8 ~ iOS11.

Objective-C

#pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [wek.backForwardList performSelector:NSSelectorFromString(@"_removeAllItems")]; #pragma clang diagnostic pop 

Swift 4

webView.backForwardList.perform(Selector(("_removeAllItems"))) 

!!!!NOTE!!!! THIS METHOD IS DECLARED IN WebKit Open Resource, not a public method。



回答3:

Reading in the documentation you can get WKBackForwardList for the WKWebView. After that you can find the first item in the backList of WKBackForwardList and after that to use: func go(to: WKBackForwardListItem) -> WKNavigation? And with this you can clean the history up to the first url.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!