WKWebViewのログイン保持
iOSでWebページを表示するために使用するWKWebView
今回、WKWebViewでのログイン保持でハマったためワークアラウンドを書いておく
今回想定するアプリ
一度webviewに行った後、webview内でログインを行う。
その後もう一度viewに戻り、再度webviewを開く。
この時、ログインが保持されていないという現象にあった。
どうしてこうなる
どうもセッションcookieをWKWebViewがストアしておかないことによるものらしい。
nsmutableurlrequest - Losing cookies in WKWebView - Stack Overflow
iOS WKWebView Tips | Professional Programmer
必要なcookieを調べて、WKWebViewから抜いて直接NSHTTPCookieStorageに突っ込めたりしないかと考えたが、そもそもWKWebViewからセッションcookieを抜くことができないっぽい。
解決策
解決策というか、ワークアラウンドなのだが、なんならバッドノウハウかもしれないので、ご意見があったらうかがいたいのだが。 今回は、上記二つ目のリンクでも述べられているWKProcessPoolを活用することにした。
WKProcessPoolとは、複数のwebview間でWeb Content Processを共有するためのものだ。
WKProcessPool - WebKit | Apple Developer Documentation
これを活用すると、cookieが複数のwebviewで(確かめてないから本当かわからないが)リアルタイムに共有されるらしい。
が、リアルタイムというのは今回はあまり重要ではない。
今回重要なのはWeb Content Processが共有されるという点だ。
つまり、同じWKProcessPoolを使うwebview間であれば、その存在が時系列上ずれていたとしてもセッションcookieを共有できるはずと考えた。
なので
extension WKProcessPool { static let shared = WKProcessPool() } class ViewController: UIViewController { override func viewDidLoad() { let configuration = WKWebViewConfiguration() configuration.processPool = WKProcessPool.shared let webview = WKWebView(frame: .zero, configuration: configuration) #中略 } }
というようにしてやると良い。
複数のViewControllerで使わないのであれば、WKProcessPoolはシングルトンっぽくしなくても、propertyとしてもってやればいいだろう。
ここで注意しなければいけないのは、WKWebViewConfigurationはWKWebViewのinitializerに渡してやらなければならないという点だ。
let webview = WKWebView() webview.configuration.processPool = WKProcessPool.shared
のようにやった場合はうまくいかなかった。
今度時間がある時にWKWebViewのコードを呼んで理由を探そうと思う。