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:
->
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?
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。
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")
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With