iosswiftwkwebviewconfiguration

WKWebViews (multiple) - sharing cookies, localStorage in Swift


I'm having such an irritating issue. I have a UITabBar application with 5 tab bar buttons. Each hooked up to a viewController: FirstViewController, SecondViewController etc.

In each of the 5 ViewControllers I have a WKWebView. The 5 WKWebViews display sections of an eCommerce website. For example, tab 1 shows home, tab 2 shows cart etc.

In order for the app to work, I need all 5 WKWebViews to share all cookies, localStorage, IndexDB.

Right now, I'm doing this:

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
}

Now in SecondViewController, I simply do this:

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
}

When I run the project, the cookies, localStorage, IndexDB information from WKWebView in FirstViewController is not shared with SecondViewController - even though according to me, I'm re-using the same configA for both.


Solution

  • I think it is best if you use SFSafariViewController for your needs.

    As the documentation states:

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

    It means, that it is going to use the same cookies and data from the Safari browser, which is even better. If I am not mistaken, the user can be logged in through Safari, and when he comes to your app, he will not have to log in again.

    Here is the full documentation for it:

    SFSafariViewController

    Update:

    If you still want to do what you already started, according to this answer here in Objective-C, this is the solution in 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
    }