看起来WKWebView的backForwardList
是只读的,但我看到人们有一些非常神奇的东西来解决这个问题。我需要找出一些清除WKWebView历史的方法。任何想法我怎么可能这样?到目前为止,我尝试了一些失败的技巧:
->
无效。我见过人们谈论合成属性和扩展课程,但我真的不知道它是如何工作的,也无法弄明白。还有其他想法吗?
答案 0 :(得分:4)
此代码编译,但我没有测试过它......
首先,我将WKWebView
子类化为使用我自己的backForwardList
子类重写WKBackForwardList
。
然后,在我的WKBackForwardList
子类中,我可以覆盖backItem
& forwardItem
使它们返回nil,而不是让它们查看各自的列表(这很可能是默认实现)。
或者我可以覆盖backList
& forwardList
与WKWebView
中使用backForwardList
的方式相同。我这样做是为了添加一个setter,这将允许我从列表中删除项目。
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")
}
}
答案 1 :(得分:2)
关注iOS8~iOS11。
目标-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")))
!!!!注!!!!这种方法在WebKit Open Resource中声明,而不是公共方法。
答案 2 :(得分:2)
由于Apple紧密锁定WKBackForwardList
的界面,并且对published public interfaces以外的开发人员严格要求严格,因此您有两种选择:
最简单的方法(当然也是Apple的意图)是创建一个新的WKWebView
并用它替换当前的clearHistory()
。实施此解决方案并不难,因为您可能必须从旧实例复制到新实例的配置数量非常有限。您甚至可以创建一个为您执行此操作的包装器视图,这样您只需要调用WKWebView
,包装器视图就可以为您进行基础交换。
如果由于某种原因而无法替换// At initialization, ensure that urlA is the first item in the history
let webview = WKWebView()
// ... whatever other init you need
webview.load(URLRequest(url: urlA))
的实例,则可以利用历史记录的一维性质来清除历史记录,最多可以减少两个项目 >。恐怕您无法清除得更远。要将URL清除为两个URL,假设它们存储在值urlA和urlB中,您可以这样做:
func clearHistory() {
// First we make sure the webview is on the earliest item in the history
if webview.canGoBack {
webview.go(to: webview.backForwardList.backList.first)
}
// Then we navigate to our urlB so that we destroy the old "forward" stack
webview.load(URLRequest(url: urlB))
}
然后“清除”历史记录:
+{}
答案 3 :(得分:1)
阅读文档可以获取WKWebView的WKBackForwardList。
之后,您可以在WKBackForwardList的backList中找到第一项,然后使用:
func go(to: WKBackForwardListItem) -> WKNavigation?
这样您就可以清除历史记录直到第一个URL。