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