【Swift】WKWebViewでCookieを取得する

# はじめに
いま、私はUIKitの練習としてQiitaのモバイル版を作成してます。
しかし、Qiitaモバイルを作成にあたって問題点があることに気づきました。
Qiitaの公式APIにはタイムラインやトレンドなどを取得できるAPIが存在しません。

ではどうするか。

そういう時はCookieを使おう！！
というわけでWKWebViewを使用してQiitaのログイン時Cookieを取得します。

# 流れ
Qiitaのログイン画面を表示
↓
ユーザーがログイン
↓
ホームに遷移したらCookieを取得

# 実装
今回は`KeychainAccess`を使用してログイン完了時に保存してます。
```swift
import UIKit
import WebKit
import KeychainAccess

class WebViewController: UIViewController {

    var webView: WKWebView!

    let keychain = Keychain(service: "com.Qiita")

    var observers = [NSKeyValueObservation]()

    override func viewDidLoad() {
        super.viewDidLoad()
        webView = WKWebView(frame: view.frame)
        view.addSubview(webView)

        let request = URLRequest(url: URL(string: "https://qiita.com/login?redirectTo=%2F")!)
        webView.load(request)

        observeUrl()
    }

    func observeUrl() {
        observers.append(webView.observe(\.url, options: .new) { _, _ in
            guard let url = self.webView.url else { return }
            if url == URL(string: "https://qiita.com/") {
                self.getCookies()
            }
        })
    }

    func getCookies() {
        webView.configuration.websiteDataStore.httpCookieStore.getAllCookies() { (cookies) in
            for cookie in cookies {
                if cookie.domain.contains("qiita.com") {
                    self.keychain["\(cookie.name)"] = "\(cookie.value)"
                }
            }
            let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
            let vc = storyboard.instantiateViewController(withIdentifier: "user")
            vc.modalPresentationStyle = .fullScreen
            self.present(vc, animated: true)
        }
    }
}
```

# 解説
## インポート
`WKWebView`を使用できるようにします。
```swift
import WebKit
```

## WKWebViewの表示
```swift
webView = WKWebView(frame: view.frame)
view.addSubview(webView)
```

## Qiitaのログイン画面の表示
```swift
let request = URLRequest(url: URL(string: "https://qiita.com/login?redirectTo=%2F")!)
webView.load(request)
```

## URLの監視
WKWebViewが現在表示しているURLを監視します。
URLが`https://qiita.com/`であった場合`getCookie`を実行します。
```swift
func observeUrl() {
    observers.append(webView.observe(\.url, options: .new) { _, _ in
        guard let url = self.webView.url else { return }
        if url == URL(string: "https://qiita.com/") {
            self.getCookies()
        }
    })
}
```

## Cookieの取得
実行時に表示されている画面のCookieを取得します。
```swift
func getCookies() {
    webView.configuration.websiteDataStore.httpCookieStore.getAllCookies() { (cookies) in
        for cookie in cookies {
            if cookie.domain.contains("qiita.com") {
                self.keychain["\(cookie.name)"] = "\(cookie.value)"
            }
        }
        let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
        let vc = storyboard.instantiateViewController(withIdentifier: "user")
        vc.modalPresentationStyle = .fullScreen
        self.present(vc, animated: true)
    }
}
```
関数上部の以下の部分では取得したCookieを保存しています。
```swift
for cookie in cookies {
    if cookie.domain.contains("qiita.com") {
        self.keychain["\(cookie.name)"] = "\(cookie.value)"
    }
}
```
関数下部の以下の部分ではホームへ自動画面遷移させています。
```swift
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let vc = storyboard.instantiateViewController(withIdentifier: "user")
vc.modalPresentationStyle = .fullScreen
self.present(vc, animated: true)
```

# 完成動画
![login_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/c1da9733-e694-0b5e-ae22-fc32cc500acf.gif)

# おわり
Cookie最強！！