我们如何为多个 UITab 使用相同的 WKWebView

Posted

技术标签:

【中文标题】我们如何为多个 UITab 使用相同的 WKWebView【英文标题】:How do we use same WKWebView for multiple UITab 【发布时间】:2020-11-26 10:53:22 【问题描述】:

我想创建一个带有多个标签栏的应用。但是每个选项卡,我都会使用 Web 视图。

问题:

    是否可以使用相同的 WKWebView(重用)?我该怎么做?。

有人可以用最好的方法帮助我吗?我是 swift 和 ios 的新手。

【问题讨论】:

不,没有这样的规定可以重用 WKWebView。您必须在要使用的任何地方创建新的 Web 视图实例。 您确定需要重复使用它吗?每次更改标签WKWebView 时都会花费一些时间来呈现网页内容。将来当您需要与WKWebView 代表一起工作时,会遇到很多麻烦。但总的来说,是的,您可以通过使用当前配置保存WKWebView 的实例并通过导航发送它来重用它,或者实现NSCopying 并复制WKWebView 我想你可以用UIDocument来做到这一点。 @Andrew:为每个选项卡使用不同/新对象意味着更好?是的,我完全依赖于委托方法,因为我需要为每个屏幕处理 JS 到 Native 的通信。 不完全是,我想重用它。我需要一个更好的建议。我是否应该重用 webview 或我重新创建 webview 的每个本机菜单(选项卡)?我的用例,1. 在每个选项卡上呈现网页。 2. 处理从 webview 到 Native 的动作,反之亦然。 【参考方案1】:

所以我认为,您最大的问题是为什么要在每个标签上重复使用 WKWebView 是共享 cookie:

在这种情况下,我们可以避免重用并创建一种cookie管理器:

// SharedCookieManager.swift


final class SharedCookieManager: NSObject 
    
    // Singleton manager
    static let `default` = SharedCookieManager()
    private override init()  super.init() 
    
    // All cookies taht we have on every WKWebView
    var cookies: Set<HTTPCookie> = []
    // Callback helping to observe changes in our set
    var cookieUpdateCallback: ((_ cookies: [HTTPCookie]) -> Void)?
    
    // Append method
    func appendCookies(_ cookies: [HTTPCookie]) 
        cookies.forEach( [weak self] in
            self?.cookies.insert($0)
        )
    

我们经理的用例:


// FirstTabViewController.swift

class FirstTabViewController: UIViewController, WKHTTPCookieStoreObserver 
    
    var webView: WKWebView? 
        didSet 
            SharedCookieManager.default.cookieUpdateCallback =  [weak self] newCookies in
                self?.webView?.configuration.websiteDataStore.httpCookieStore.getAllCookies( oldCookies in
                    Set(newCookies).symmetricDifference(oldCookies).forEach(
                        self?.webView?.configuration.websiteDataStore.httpCookieStore.setCookie($0, completionHandler: nil)
                    )
                    self?.webView?.reload()
                )
            
        
    
    
    override func viewDidLoad() 
        super.viewDidLoad()
        
        WKWebsiteDataStore.default().httpCookieStore.add(self)
        let webView = WKWebView()
        
        SharedCookieManager.default.cookies.forEach( [weak webView] in
            webView?.configuration.websiteDataStore.httpCookieStore.setCookie($0)
        )
    
    
    func cookiesDidChange(in cookieStore: WKHTTPCookieStore) 
        cookieStore.getAllCookies(
            SharedCookieManager.default.appendCookies($0)
        )
    

对于您在TabBar 中使用的每个ViewController 都相同

它不是“金锤”,我不能说它会 100% 有效,但您可以尝试使用此示例来实现您的目标。希望它会有所帮助。

【讨论】:

【参考方案2】:

同一个对象可以在多个地方使用,要么你需要创建一个对象的副本,要么创建一个类的新对象。并实施一种方法使两者保持同步。

【讨论】:

以上是关于我们如何为多个 UITab 使用相同的 WKWebView的主要内容,如果未能解决你的问题,请参考以下文章

如何为相同的资源使用多个路由

Xcode iOS - 使用相同资源的多个测试失败 - 如何为多个测试使用 1 个资源?

Angular Material Mat-Stepper:如何为多个步骤使用相同的表单组?

如何为多个docker容器使用相同的python映像?

如何为多个产品托管相同的代码?

如何为具有相同名称的多个文本区域添加ckeditor