如何清除WKWebView的WKBackForwardList?

Che*_*het 6 objective-c ios swift wkwebview

看起来backForwardListWKWebView的内容是只读的,但我已经看到人们有一些非常神奇的东西可以解决这个问题.我需要找出一些清除WKWebView历史的方法.任何想法我怎么可能这样?到目前为止,我尝试了一些失败的技巧:

  • 使用keyValue:forKey不起作用.
  • 使用C指针->不起作用.

我已经看到人们谈论合成属性和扩展课程,但我真的不知道它是如何工作的,无法弄明白.还有其他想法吗?

xu *_*ong 6

在 iOS8 ~ iOS11 上写的。

目标-C

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

斯威夫特 4

webView.backForwardList.perform(Selector(("_removeAllItems")))
Run Code Online (Sandbox Code Playgroud)

!!!!笔记!!!!这个方法是在 WebKit 开放资源中声明的,而不是公共方法?

  • 使用这种方法肯定会被拒绝。很简单,WKBackForwardList api doc中没有列出,所以是私有的api。当 Apple 决定在未来版本的 iOS 中更改该签名时,这是一种非常糟糕的方法来解决该问题并导致崩溃。 (2认同)

nyg*_*nyg 2

这段代码可以编译,但我还没有测试过......

首先,我将子类WKWebView化为backForwardList我自己的WKBackForwardList.

然后,在我的WKBackForwardList子类中,我可以重写backItem&forwardItem以使它们返回 nil,而不是让它们查看各自的列表(这很可能是默认实现)。

或者我可以像使用一样覆盖backList& 。我这样做是为了添加一个设置器,它允许我从列表中删除项目。forwardListWKWebViewbackForwardList

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")
    }
}
Run Code Online (Sandbox Code Playgroud)

  • backForwardList 在导航过程中永远不会改变。它在我的应用程序中仍然是空的。怎么了? (3认同)
  • 不幸的是,这个绝妙的想法行不通。看起来“backList”只是一个派生属性,因此 WebKit 内部不使用它来存储实际访问的项目。 (3认同)
  • 确实,不起作用。解决方法是创建一个新的 WKWebView 并传递旧的配置。 (2认同)