8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

iOSのWebViewで任意のCookieを送信するには

Last updated at Posted at 2022-02-01

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

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?