LoginSignup
7

More than 3 years have passed since last update.

WKWebViewのCookieを使ってURLSessionでWEBAPIを叩く

Posted at

経緯

iOSアプリを開発しているとき、WKWebViewでユーザー認証をしたあとにその認証情報(Cookie)を使ってWEBAPIを叩いてユーザーの情報等を把握したいことがあります。
しかしながら、どうやらWKWebViewとWEBAPIを叩く時に標準的に使われるURLSessionではCookieは暗黙的に共有されていないようです。
そこで、URLSessionでWKWebViewのCookieを使用するためにはどのようにしたらいいのかを書いていきます。
もしも、WKWebViewのCookieを使って簡単にWEBAPIを叩く方法がある場合は教えてください!!

流れ

  1. WKWebViewからCookieを取得する。
  2. CookieをHTTPヘッダーに埋め込む形に変形させる
  3. URLSessionでGET(POST)するときにHTTPヘッダーにCookieを追加

WKWebViewからCookieを取得する

特定のドメインに利用されるCookieをWKWebViewから取得します。この工程は先ほどの流れの1と2です。
今回はCookieを常に保持しておきたかったので、UserDefaultsにCookieを保存しています。

hoge.swift
 var stringCookie:String = ""
        webview.configuration.websiteDataStore.httpCookieStore.getAllCookies() {(cookies) in
            // [参考]:取得したcookiesは[HTTPCookie]型です。cookiesにはWKWebViewの全ての Cookieが含まれます。
            for eachcookie in cookies {
                if eachcookie.domain.contains("ドメイン名。ワイルドカードなら `.example.com` 等と入力する"){
                    stringCookie += "\(eachcookie.name)=\(eachcookie.value);" //HTTPヘッダーの形に変形
                }
            }
            // UserDefaults のインスタンス UserDefaultsに保存するかは自分の使い方に合わせてください
            let userDefaults = UserDefaults.standard
            // UserDefaults に特定のドメインのCookieを保存。
            userDefaults.set(stringCookie,forKey: "stringCookie")
            userDefaults.synchronize()
        }

これにて特定ドメインのCookieを取得して、HTTPヘッダーに挿入されるフォーマットに変形できます。
この変形後のCookieを使ってWEBAPIを殴ります。

URLSessionを使ってWEBAPIを叩く

先ほどの工程の3にあたります。あとは通常通りWEBAPIを叩く際にHTTPヘッダーにCookieを追加するだけです。

hogehoge.swift
       // URL生成
        let requestUrl:String = "WEBAPIのURLをここに記述"
        guard let url = URL(string: requestUrl) else {
            // URL生成失敗
            return
        }

        // リクエスト生成
        var request = URLRequest(url: url)
        // UserDefaults のインスタンス
        let userDefaults = UserDefaults.standard
        if let stringCookie = userDefaults.string(forKey: "stringCookie"){
            // UserDefaultsからCookieを取得してHTTPヘッダーに追加。
            request.setValue(stringCookie, forHTTPHeaderField: "Cookie")
        }

        let session = URLSession.shared
        let task = session.dataTask(with: request) { (data:Data?,response:URLResponse?, error:Error?) in
            // 通信完了後の処理
            guard let data = data else {
                // データなし
                return
            }
             // jsonをそのまま表示
             do {
                 let object = try JSONSerialization.jsonObject(with: data, options: [])
                 print(object)
             } catch let e {
                 print(e)
             }
        }
        // 通信開始
        task.resume()

重要なのは
request.setValue(stringCookie, forHTTPHeaderField: "Cookie") です。この部分でCookieを付加しています。
このソースコードではJSONのパース等は行なわず、取得したJSONをそのまま表示しています。
JSONをパースする場合はこちらの記事等を参考にするといいと思います。
SwiftでQiitaのAPIを表示させる。

参考

あとがき

もし、こうしたらいいとかあったら教えてください。
この方法はWKWebViewとURLSessionのCookie共有がうまくいかなくて逃避しつつ涙目になりながら考えてました。
そもそも、ネット上ではiOSのWebViewに関しての情報が錯綜している気がします。原因は

  • Objective-C と Swiftの情報が混ざっている
  • UIWebView と WKWebView の情報が混ざっている。

なんじゃないかなぁ・・・
image.png
オワコンは草

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
What you can do with signing up
7