iOSのWebViewで任意のCookieを送信する場合、WKHTTPCookieStoreにCookieをセットすることで実現できます。
実装パターンとしてはアプリの自動ログインなど、API経由などで取得したセッションCookieを送信するなどがあります。
結構前の話になりますが、WKHTTPCookieStoreが使えなかった時代(iOS11未満)は、WKWebViewのevaluateJavaScript
なんかを使ってJavaScriptでdocument.cookie = "foo=bar";
のようにセットしたりしていました。
この場合、初回ロード時にはタイミング的には当然このJavaScriptが実行前の状態になるので未ログイン状態の画面になってしまうため、NSMutableURLRequestでヘッダにCookieヘッダを詰め込む必要があったり、いろいろ苦労した思い出があります。
以下は、WebViewにCookieをセットする簡単な例です。
import WebKit
class PrivateWebViewController: UIViewController {
var webView: WKWebView!
var config: WKWebViewConfiguration!
var firstLoadURL = URL(string: "https://mgre.jp")!
override func viewDidLoad() {
super.viewDidLoad()
config = WKWebViewConfiguration()
webView = WKWebView(frame: view.frame, configuration: config)
view.addSubview(webView)
// Cookieオブジェクトを作成
let cookie = HTTPCookie(properties: [
HTTPCookiePropertyKey.name: "foo",
HTTPCookiePropertyKey.value: "var",
HTTPCookiePropertyKey.domain: firstLoadURL.host!,
HTTPCookiePropertyKey.path: "/"])!
// Cookieをセット
config.websiteDataStore.httpCookieStore.setCookie(cookie) { [weak self] in
guard let self = self else { return }
self.webView.load(URLRequest(url: self.firstLoadURL))
}
}
}
WKHTTPCookieStore登場後も、WebViewのインスタンス化前にCookieをセットしないと何故かCookieが送れないという問題などもあり、いろいろ苦労した記憶がありますが、シミュレータで試した限りではiOS13以降はそれを意識する必要はなくなっているように見えます。
WebView間のCookieをリアルタイムで同期する場合
異なるWebViewインスタンスの間でCookieを同期する場合、WebViewにそれぞれWKWebsiteDataStore.defaultをセット(デフォルト状態)したうえで、同じWKProcessPoolをセットします。
同じWKWebsiteDataStoreを参照させることでおなじCookie情報を取得でき、WKProcessPoolを同じにすることでリアルタイムにCookieがWebView間で同期されるようになります。
WebView間で同じWKWebsiteDataStoreをセットしていればCookieは同期されますが、同じWKProcessPoolをセットしていないとリアルタイムにCookieが同期されず、遅延が発生します。
別のやり方としては、WKWebsiteDataStore.nonPersistentを使って同じインスタンスを複数のWebViewにセットすればWebView間でCookieを共有することは可能です。
WKWebsiteDataStoreとは
WebViewでアクセスしたページのキャッシュ等のデータを保存します。
WebViewはデフォルトでWKWebsiteDataStore.defaultがセットされており、WKWebsiteDataStore.default を使った場合、WebViewのCookieはアプリ内に保存されて永続化されるため、WebView内でログイン状態をアプリ再起動後も維持できます。
WKWebSiteDataStore.default()で返されるのは同じインスタンスです。
WKProcessPoolとは
Webコンテンツプロセスを共有するもので、同じWKProcessPoolをセットしたWebView間はリアルタイムにCookieが同期されます。
WKProcessPoolが同じでも、WKWebsiteDataStore.nonPersistent()のWebViewでセットしたCookieは他のWebViewには同期されないようです。
SafariViewで任意のCookieを送信できるか
SafariViewはカスタムできないため、任意のCookieを送ることはできません。
ただ、シミュレータで確認した限りではCookieはアプリ内の「/SystemData/com.apple.SafariViewService/Library/Cookies/Cookies.binarycookies」に保存され、永続化されるため、SafariView内でログインした状態はアプリを再起動しても維持することは可能です。
ランチェスターではアプリエンジニア社員を募集しております!
まずはざっくばらんにお話しさせてください。下記からご応募お待ちしております。
▼https://herp.careers/v1/lanchester/stnR3oAOKkwJ
▼https://www.wantedly.com/companies/lanchester
▼採用動画について:https://moovy.jp/job/651