WKWebViews(多个)- 在 Swift 中共享 cookie、localStorage

WKWebViews (multiple) - sharing cookies, localStorage in Swift

我遇到了一个令人恼火的问题。我有一个带有 5 个选项卡栏按钮的 UITabBar 应用程序。每个都连接到一个 viewController:FirstViewController、SecondViewController 等

在 5 个 ViewController 中的每一个中,我都有一个 WKWebView。电子商务网站的 5 个 WKWebViews 显示部分。例如,选项卡 1 显示主页,选项卡 2 显示购物车等。

为了让应用程序运行,我需要所有 5 个 WKWebView 共享所有 cookie、localStorage、IndexDB。

现在,我正在这样做:

FirstViewController

class FirstViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
let uniqueProcessPool = WKProcessPool()
let websiteDataStoreA = WKWebsiteDataStore.nonPersistent()

..

class YourModelObject {
static let sharedInstance = YourModelObject()
let configA = WKWebViewConfiguration() 
}

override func loadView() {       
let model = YourModelObject.sharedInstance
//so I believe I'm doing the right thing here setting this
model.configA.processPool = uniqueProcessPool
model.configA.websiteDataStore = websiteDataStoreA       
webView = WKWebView(frame: .zero, configuration: model.configA)
webView.navigationDelegate = self
self.webView.scrollView.delegate = self 
view = webView
}

现在在 SecondViewController 中,我只是这样做:

override func loadView() {       
//am I doing something wrong here - like creating another instance of configA, instead of re-using - and if so, how do I re-use what was created in FirstViewController?
let model = FirstViewController.YourModelObject.sharedInstance            
webView = WKWebView(frame: .zero, configuration: model.configA)
webView.navigationDelegate = self
self.webView.scrollView.delegate = self
view = webView
}

当我 运行 项目时,FirstViewController 中 WKWebView 的 cookies、localStorage、IndexDB 信息不会与 SecondViewController 共享 - 尽管根据我的说法,我正在为两者重新使用相同的 configA。

我认为最好使用 SFSafariViewController 来满足您的需要。

如文档所述:

In iOS 9 and 10, it shares cookies and other website data with Safari.

这意味着,它将使用与 Safari 浏览器相同的 cookie 和数据,这甚至更好。如果我没记错的话,用户可以通过Safari登录,当他来到你的应用时,他就不用重新登录了。

这是它的完整文档:

SFSafariViewController

更新:

如果您仍然想做已经开始的事情,根据 this 在 Objective-C 中的回答,这是 Swift 中的解决方案:

You need a place where you would store the persistent 'process pool'. In your case, it is YourModelObject singleton

class YourModelObject {
    static let sharedInstance = YourModelObject()
    let processPool = WKProcessPool() 
}

Use the shared processPool before initializing the webView. This is the initialization function which you would call in the loadView() for every viewController:

override func loadView() {
    super.loadView() //don't forget this line
    
    setupWebView()
}

private func setupWebView() {

    let config = WKWebViewConfiguration()
    config.processPool = YourModelObject.sharedInstance.processPool
    self.webView = WKWebView(frame: .zero, configuration: config)
    self.webView.navigationDelegate = self
    self.webView.scrollView.delegate = self 
    self.view = self.webView
}