1

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.

Dawie
  • 15
  • 4

1 Answers1

1

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
}
Starsky
  • 1,829
  • 18
  • 25
  • Thanks for the suggestion. However, I did go read about SFSafariViewController and I see Apple's documentation states that: "If your app lets users view websites from anywhere on the Internet, use the SFSafariViewController class. If your app customizes, interacts with, or controls the display of web content, use the WKWebView class." And that is exactly what I'm doing - I'm changing the content / display - and also, my entire app is already using so many WKWebView features - changing it now will be quite a task. Any other suggestions to make it work with WKWebView? – Dawie Oct 28 '20 at 16:00
  • Sorry I missed your other suggestion that's in Obj-C - going to check it out @Starsky - and, I did check it out now and the solution is part of what I used for my code above - but it didn't work. I don't know if I'm setting the instance correctly and then re-using it, or if I'm creating a new instance every time I try to access it from each of the 5 WKWebViews. – Dawie Oct 28 '20 at 16:05
  • @Dawie I provided you with the exact pieces of code which you need to use. If you initialize the `processPool` inside the `YourModelObject` singleton, and then pass around this `processPool`, you will not instantiate each time a new object, but will pass the same object everywhere. You need to do exactly as in the code provided, but not with `model.configA` and etc. – Starsky Oct 28 '20 at 16:16
  • @Dawie See my updated answer. I wrote the specific code you will need to share across all `webView`s. – Starsky Oct 28 '20 at 16:25
  • O.M.G. you saved my life I can't believe it's actually working now. Thank you, thank you, thank you. I used your code snippets above and modified my singleton and all good. – Dawie Oct 28 '20 at 16:28
  • I am glad this solved your problem! ))) Happy coding! – Starsky Oct 28 '20 at 16:40