タマネギプログラマーの雑記

たまねぎ剣士的なニュアンス

WKWebViewのログイン保持

iOSでWebページを表示するために使用するWKWebView
今回、WKWebViewでのログイン保持でハマったためワークアラウンドを書いておく

今回想定するアプリ

f:id:gaoxin-xixxix:20171004234507p:plain

一度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のコードを呼んで理由を探そうと思う。