複数WKWebViewがある時の挙動を調べてみました。
まずは下のようにWKWebViewを2つ並べます。
import UIKit import WebKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let rect1 = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height / 2 - 10) let webView1 = WKWebView(frame: rect1) webView1.load(URLRequest(url: URL(string: "https://google.co.jp")!)) view.addSubview(webView1) let rect2 = CGRect(x: 0, y: view.frame.height / 2 + 10, width: view.frame.width, height: view.frame.height / 2 - 10) let webView2 = WKWebView(frame: rect2) webView2.load(URLRequest(url: URL(string: "https://google.co.jp")!)) view.addSubview(webView2) } }
実行すると下のようにWebViewが2つ並んでいる事が分かります。
この状態で片方でTwitterにログインするともう一方でもログイン状態になります。
以前「一緒のWKProcessPool
を使えばcookieも同期される」と聞いてたので、同じWKProcessPool
を使ってないのに共通化されてたのは予想外でした。
念の為2つのWKProcessPoolを比較したんですが別のインスタンスでした。
print(webView1.configuration.processPool === webView2.configuration.processPool) // → false
公式ドキュメントを読んだ所、process poolが一緒なら同じprocessを使うとあるので、これはcookieの共通化に関わっていそうです。
The process pool associated with a web view is specified by its web view configuration. Each web view is given its own Web Content process until an implementation-defined process limit is reached; after that, web views with the same process pool end up sharing Web Content processes.
WKProcessPool - WebKit | Apple Developer Documentation
その後調べていたら、cookie共通化にはWKProcessPoolではなくWKWebsiteDataStoreを使うという記事を見つけました。
もしかすると「cookieが共通化されているのは同じWKWebsiteDataStoreを使っているからでは?」と思い実験してみました。
試しに下のようなコードを書いたらたしかに同じWKWebsiteDataStoreを使っていました。
print(webView1.configuration.websiteDataStore === webView2.configuration.websiteDataStore) // → true
どうやらWKWebViewはデフォルトでWKWebsiteDataStore.default
を使っているようです。
webView1.configuration.websiteDataStore === WKWebsiteDataStore.default()
違うWKWebsiteDataStore
を使ったらどうなるか確認する為、下のように片方のwebsiteDataStoreにWKWebsiteDataStore.nonPersistent()をセットしました。
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let conf1 = WKWebViewConfiguration() conf1.websiteDataStore = WKWebsiteDataStore.nonPersistent() let rect1 = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height / 2 - 10) let webView1 = WKWebView(frame: rect1, configuration: conf1) webView1.load(URLRequest(url: URL(string: "https://google.co.jp")!)) view.addSubview(webView1) let conf2 = WKWebViewConfiguration() let rect2 = CGRect(x: 0, y: view.frame.height / 2 + 10, width: view.frame.width, height: view.frame.height / 2 - 10) let webView2 = WKWebView(frame: rect2, configuration: conf2) webView2.load(URLRequest(url: URL(string: "https://google.co.jp")!)) view.addSubview(webView2) } }
実行すると、cookieが共通化されていない事が分かります。
その後WKWebsiteDataStore
は別、WKProcessPool
は同じものを使っているという状態も試したんですが、cookieは共通化されませんでした。
そのため、cookieの共通化はWKWebsiteDataStore
に任せるのが良さそうです。
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let processPool = WKProcessPool() let conf1 = WKWebViewConfiguration() conf1.websiteDataStore = WKWebsiteDataStore.nonPersistent() conf1.processPool = processPool let rect1 = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height / 2 - 10) let webView1 = WKWebView(frame: rect1, configuration: conf1) webView1.load(URLRequest(url: URL(string: "https://google.co.jp")!)) view.addSubview(webView1) let conf2 = WKWebViewConfiguration() conf2.processPool = processPool let rect2 = CGRect(x: 0, y: view.frame.height / 2 + 10, width: view.frame.width, height: view.frame.height / 2 - 10) let webView2 = WKWebView(frame: rect2, configuration: conf2) webView2.load(URLRequest(url: URL(string: "https://google.co.jp")!)) view.addSubview(webView2) } }